阅读 474

安卓学习

安卓的一些学习总结

安卓学习总结

四大组件

1.Activity:是所有Android程序的门面,凡是在应用中看到的东西都放这里面,就是界面的意思
2.Service:无法看到它,在后台运行,即使退出程序任然可以继续运行
3.BroadbcastReceiver:允许应用接受各处的广播消息,比如电话和短信,
4.ContentProvidr:为应用程序之间共享数据成为可能,比如读取系统通讯录中的联系人
复制代码

注册主Activity setContentView()引入布局

所有的Activi都在AndroidManifest.xml中注册,以下是注册主Activity

    <activity android:name=".MainActivity">
            <intent-filter>
           //这两行代码是注册主Activity
            //决定应用的入口Activity,也就是我们启动应用时首先显示哪一个Activity。
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
复制代码

然后是mainActivity代码

所有自定义的Activity都要继承它获子类,才能拥有它的特性

class MainActivity : AppCompatActivity() {
   //这个方法是Activity被创建必定被执行的方法
    override fun onCreate(savedInstanceState: Bundle?) {
      //调用父类的构造函数,savedInstanceState保存当前Activity的状态信息
        super.onCreate(savedInstanceState)
       //设置当前Activity内容
        setContentView(R.layout.activity_main)
    }
}
复制代码

安卓日志Log

//第一个参数一般闯入类名,对打印信息过誉
//msg要打印的内容
Log.d(tag,msg)

复制代码

Toast的使用

Toast可以使用它在程序中将一些短小的消息通知给用户,这些消息在一段时间中消失,不占屏幕空间

setOnclickListener()设置监听器

点击按钮就会执行监听器,弹出Toast的功能要在Onclick()方法中编写

Toast用法:

1.通过静态方法makeToast()创建一个Toast对象

Toast.makeToast(this,"提醒内容",时长).show()
//时长有两个 Toast.LENGTH_SHORT
            Toast.LENGTH_LONG
复制代码
//为button设置了一个监听器,但点击时,弹出Toast的文本内容 
val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
            Toast.makeText(this,"提示逆",Toast.LENGTH_LONG).show()
        }
复制代码

menu的使用

作用节约屏幕空间

右击res-》兴建一个叫menu的目录-》在此目录下右击new Menu respurce file-》文件名main

**item这个标签用来创建具体的某一个菜单项 **

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/add_item"
    android:title="add_item"/>
    <item
        android:id="@+id/remove_item"
        android:title="remove_item"/>
</menu>
复制代码

然后再FirstActivity来重写方法

函数onCreateOptionsMenu()为创建Menu菜单的项目

函数onOptionsItemSelected()为处理菜单被选中运行后的事件处理

inflate方法的使用

infalte(这个参数是通过那个资源文件创建菜单,创建的菜单项添加到那个Menu对象当中)
复制代码
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
          super.getMenuInflater()
           menuInflater.inflate(R.menu.main,menu)
          return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
          when(item.itemId){
              R.id.add_item->Toast.makeText(this,"你好",Toast.LENGTH_SHORT).show()
              R.id.remove_item->Toast.makeText(this,"你不好",Toast.LENGTH_SHORT).show()
          }
        return true
    }
}
复制代码

摧毁一个Activity: finish()方法

方式一:在监听器中

    val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
          finish()
        }
复制代码

方式二:手机back键

使用Intent在Activity中穿梭

主Activity跳转到其它Activity

显示Intent

//第一个参数就是主Activi作为上下文,第二个参数就是传入的要启动的目标Activity
val intent=Intent(this,SecondActivity::class.java)
//启动
startActivity(inten)
复制代码

第一步兴建一个Activity,在主FirstActivity中修改代码,

       val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
         val intent=Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }
复制代码

隐式的Intent

不明确指定哪一个Activity,而是指定抽象的action和category,交由系统分析启动哪一个Activity

修改AndroidManifest.xml代码

 <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START"/>
              //这是一个默认的category
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
复制代码

在FirstActivity中启动匹配

val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
         val intent=Intent("com.example.activitytest.ACTION_START")
            startActivity(intent)
        }
复制代码

更多隐式Intent

调用系统浏览器来启动网页

将一个网址字符串解析成一个Uri对象
在通过Intent的setdata将Uri对象传递出去
intent.data=Uri.parse("https://www.baidu.com")
复制代码
val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
            //这是安卓内置动作
            val intent=Intent(Intent.ACTION_VIEW)
            intent.data= Uri.parse("https://www.baidu.com")
            startActivity(intent)
        }
复制代码

在data标签主要匹配内容

android:scheme 用于指定数据的协议部分,如www.baidu.com中的http部分。 android:host 用于指定数据的主机名部分,如www.baidu.com中的www.baidu.com部分。 android:port 用于指定数据的端口部分,一般紧随在主机名之后,如www.rowyer:8080/mypath中的808… android:path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容,如www.rowyer:8080/mypath中的/my… android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定。 ———————————————— 兴建一个Activity,修改注册信息

<activity android:name=".ThirdActivity" tools:ignore="AppLinkUrlError">//无视警告
            <intent-filter >
         //action显示的是android.intent.action.VIEW常量值
                <action  android:name="android.intent.action.VIEW"/>
                 <category android:name="android.intent.category.DEFAULT"/>
                 <data android:scheme="https"/>
            </intent-filter>

        </activity>
复制代码

像下一个Activity传递数据

Intent重载方法 putExtra()

intent.putExtra(第一个参数是键值用与从intent取值,第个参数是真正要传递的参数)
复制代码

修改FirstActivity中的监听器

        val button:Button=findViewById(R.id.button)
        button.setOnClickListener {
          val data="Hello,SecondActivty"
          val  intent= Intent(this,SecondActivity::class.java)
            intent.putExtra("item_data",data)
            startActivity(intent)
        }
    }

复制代码

然后打开SecondActivity,通过Lod.d日志来查看

//这里的Intent其实是调用了父类的getIntent()方法获取用与启动的SecondActovoty的Intent
//getStringExtra()这个方法是获取键值,从而获取传来的数据
val data=Intent.getStringExtra("item_data")
复制代码

返回数数据给Activity传递数据

返回数据给上一个Activity方法:SrartActivityForResult()

   StartActivityForResult(第一个参数数Intent,请求码)
复制代码

setResult()专门用来向上一个Activiry返回数据

第一个参数一般用来向上一个Activiry返回处理结果,一般使用RESULT_OK

第二个参数是把带有Intent数据传递出去

setRusult(RESULT_OK,intent)
复制代码

因为是通过startActivityForResult启动SecondActivity,在SecondActivity销毁前会回调上一个Activity的onActivityResult方法,所以我们要重写

//第一个参数是请求码,第二个参数是处理的结果,第三个参数是携带返回数据的Intent 
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
               1 ->if (resultCode== RESULT_OK){
                 val resultdata=data?.getStringExtra("item_data")
                   Log.d("FirstTctivity","data is $resultdata")
               }
           }
    }
复制代码

Activity的生命周期·

onCreate() 这个方法在Activity第一次被创建的时候调用。

onStart() 这个方法在Activity由不可见变为可见的时候调用。

onResume() 这个方法在Activity准备好和用户进行交互的时候调用。

onPause() 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。

onStop() 这个方法在Activity完全不可见的时候调用。

onDestroy() 这个方法在Activity被销毁之前调用。

onRestart() 这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

复制代码

![image-20210501155444421](/Users/king/Library/Application Support/typora-user-images/image-20210501155444421.png)


Activity回调方法 onSaveInstanceState()

当一个Activity进入停止状态时,可能就会被回收,例如:用户在Activity a的转态下启动Activity b,a就进入停止状态,但是由于系统内存不足,a就会被回收,但是但我们按下back键回到a时,还是会正常显示,但是是执行onCreat方法,这个a被重新创建,如果我们在a中有些数据,那么返回原先的数据就会消失。

** 这个onSaveInstanceState()方法是保证Activity被回收之前调用,这个方法携带一个Bundle类型参数

putString用来保存字符串

在ManActivity添加代码进行临时保存

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val end="This is a red"
        outState.putString("data_key",end)
    }
复制代码

取值修改onCreat方法

    private val tag="MainActivity"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(tag,"onCreate")
        setContentView(R.layout.activity_main)
        if (savedInstanceState!=null){
            val data=savedInstanceState.getString("data_key")
            Log.d(tag,"data is $data")
        }

复制代码

Activity的启动模式

选择启动模式

在标签指定android:luchMode属性来选择启动模式

默认启动模式之standard

如果再次启动这个Activity就会再次兴建一个新的Activity的实例

启动模式之Single Top

在栈顶已经是该Activity,再次启动可以直接使用它,不会在创建新的Activity

  <activity android:name=".ThirdActivity"
             android:launchMode="singleTop"
            tools:ignore="AppLinkUrlError">
复制代码

启动模式之SingleTask

使用SingleTask可以解决多次重复创建Activity的问题,使用这个模式,首先还在返回栈中检查有没有这个Activity实例,如果有则使用该实例,把这个Activity之上的其它Activity统统出栈


知晓当前在哪一个Activity中

首先兴建一个普通类Test继承AppCompatActivity(),并重写onCreate方法

open class Test:AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //获取类名
        Log.d("Test",javaClass.simpleName)
    }
}
复制代码

接着让这个类成为ActivityTest项目的父类

随时随地退出程序

兴建一个单例类为ActivityColler

package com.example.activitytest

import android.app.Activity

object ActivityColler {
    val Activityes=ArrayList<Activity>()

    fun  adda(activity: Activity){
        Activityes.add(activity)
    }
    fun removea(activity: Activity){
        Activityes.remove(activity)
    }
    fun finishalla(activity: Activity){
       for (activty in Activityes){
           if (!activity.isFinishing){
               activity.finish()
           }

       }
        Activityes.clear()
    }

}
复制代码

修改Test方法

open class Test:AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Test",javaClass.simpleName)
      //把正在创建的Activity添加到集合里面
        ActivityColler.adda(this)
    }
    //移除马上销毁的Activity
    override fun onDestroy() {
        super.onDestroy()
        ActivityColler.removea(this)
    }
}
复制代码

例如你在这个界面就可以单击按钮可以直接退出程序

class ThirdActivity : Test() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.third_layout)
        val button3:Button=findViewById(R.id.button3)
        button3.setOnClickListener {
            ActivityColler.finishalla(this)
        }
    }
}
复制代码

启动Activity的最佳写法

情景,例如自己开发这个SecondActivity,不清楚启动这个要传递那些数据,换一种写法可以解决

class SecondActivity : Test() {
  //静态
    companion object{
        fun  start(context: Context,data1:String,data2:String){
            val intent=Intent(context,SecondActivity::class.java)
            intent.putExtra("pramal1",data1)
            intent.putExtra("pramal2",data2)
            context.startActivity(intent)
        }
    }
  //启动方式
       val button2:Button=findViewById(R.id.Button2)
        button2.setOnClickListener {
             SecondActivity.start(this,"data1","data2")
        }
复制代码

Kotlin:标准函数和静态方法

标准函数with,run,apply

val result=with(任意类型对象){
//lambda表达式
}
复制代码

Run :特点只接受一个Lambda表达式,并且会提供调用对象的上下文,最后一行代码作为返回值返回

apply:无法指定返回值,只会返回调用对象本身

   val intent=Intent(context,SecondActivity::class.java)
            intent.putExtra("pramal1",data1)
            intent.putExtra("pramal2",data2)
            context.startActivity(intent)
        }
--------------
   val intent=Intent(context,SecondActivity::class.java).apply{
            putExtra("pramal1",data1)
           putExtra("pramal2",data2)
            context.startActivity(intent)
        }
复制代码

静态方法

class Util {
    fun doAction(){
        println("do Action")
    }
    companion object{
        //真正的静态方法
        @JvmStatic //这个注解只能加到单例类获 companion object方法上
        fun doAction2(){
            println("do Action")
        }
    }
}
//单例类,虽然不是静态方法,但是可以通过Util2.doAction3来调用
object Util2{
    fun doAction3(){
        println("doAction")
    }
}
复制代码

常用控件

TextView

TextView的文字默认左上角对齐

常用属性

			  android:gravity="center"//文字对齐方法
        android:textSize="30sp"//字体大小 
        android:textColor="#00ff00"//字体颜色
复制代码

EditText

用于和用户进行交互

<EditText
        android:id="@+id/EditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入内容"//友好提示
				android:maxLines="2"/>限制2行,超过文本向上滚动
复制代码

通过按下button按钮把EaitText的输入内容打印

package com.example.uiwidgetest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class MainActivity : AppCompatActivity(),View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button:Button=findViewById(R.id.button)
        button.setOnClickListener(this)
    }
      override fun onClick(v: View?) {
        when(v?.id){
            R.id.button->{
                val editText:EditText=findViewById(R.id.EditText)
                val puttext=editText.text.toString()
                Toast.makeText(this,puttext,Toast.LENGTH_SHORT).show()
            }
        }
    }
}
复制代码

imageView

展示图片的控件

 android:src="@drawable/img_1"//指定图片
复制代码

`动态修改图片

class MainActivity : AppCompatActivity(),View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button:Button=findViewById(R.id.button)
        button.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.button->{
              //通过这个方法该图片 
            val imageView:ImageView=findViewById(R.id.imageview)
                imageView.setImageResource(R.drawable.img_2) 
            }
        }
    }
}
复制代码

progressBar

安卓的可见属性 android:visibility

invisible:表示控件不可见 ,仍占原来位置和大小,控件类似透明转态
gone:控件不仅不可见,而且不占如何屏幕空间
visible:空间可见切默认
复制代码
//这个属性可以改成水平进度条 
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
//给进度条设置一个最大值
android:max="100
复制代码

动态更改进度条

  override fun onClick(v: View?) {
        when (v?.id) {
            R.id.button -> {
              //每次加10的进度
                val progree: ProgressBar = findViewById(R.id.prpgressBar)
                  progree.progress=progree.progress+10
            }
        }
    }
复制代码

AlertDialog

可以在当前界面弹出对话框,置于所有界面元素之上,用与提示一些重要信息

override fun onClick(v: View?) {
        when (v?.id) {
            R.id.button -> {
               AlertDialog.Builder(this).apply{
                   setTitle("This is Dialog")
                   setMessage("Something improt")
                   setCancelable(false)
                   setPositiveButton("OK"){
                       dialog, which ->
                   }
                   setNegativeButton("Cancel"){dialog, which ->  }
                   show()
               }

            }
        }
    }
复制代码

3种基本布局

线性布局LinearLayout

android:orientation="horizontal"//水平布局 默认
   android:orientation="vertical"//垂直布局
     android:layout_weight=""//布局控件的大小
复制代码

相对布局RelativeLayout

可以通过相对定位方法让控件成为布局任何方向

帧布局FrameLayout

默认左上角

        android:layout_gravity="right"//居右对齐
          android:layout_gravity="left"//居左对齐
复制代码

引入布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
  //映入布局
 <include layout="@layout/titlit"/>
</LinearLayout>
复制代码
//在主Activity中吧自带的标题栏隐藏掉 
supportActionBar?.hide()
  //用与布局和控件指定背景
 android:background="@drawable/title_bg">
 //用与指定控件的间距 	
  android:layout_margin="5dp"
复制代码

自定义布局

Context,attrs:AttributeSet):LinearLayout(context,attrs) {
    init {
      //LayoutInflater.from(context)构建一个对象
      //inflate动态加载布局
        LayoutInflater.from(context).inflate(R.layout.titlit,this)
        val button:Button=findViewById(R.id.button)
        button.setOnClickListener{
          //as强转
            val activity=context as Activity
            activity.finish()
        }
        val button2:Button=findViewById(R.id.button2)
          button2.setOnClickListener{
              Toast.makeText(context,"小伙子",Toast.LENGTH_SHORT).show()
          }
    }

}
复制代码

ListView

package com.example.listviewtest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView

class MainActivity : AppCompatActivity() {
    private val data= listOf("AAAA","BBB","CCCC","DDDD","EEEE","FFFF",
    "GGGGG","HHHHH","WWWWWW")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //适配器
        //1.传入Activity实例,2、安卓内置文件,3.数据源
        val adber=ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data)
        val listView:ListView=findViewById(R.id.listView)h
        //调用listView的setAdapter()把创建对象传递进去
        listView.adapter=adber

    }
}
复制代码

定制ListView的界面

        repeat(2){}//数据添加两遍

复制代码

//自定义适配器
class FuitAdapter(activity:Activity,val resourceId:Int,data:List<Firut>):ArrayAdapter<Firut>(activity,resourceId,data) {
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
         val view=LayoutInflater.from(context).inflate(resourceId,parent,false)
          val imageView:ImageView=view.findViewById(R.id.iamgeView)
          val textView:TextView=view.findViewById(R.id.textView)
         val firut=getItem(position)//获取当前fruit的实例
         if (firut!=null){
             imageView.setImageResource(firut.imageID)//获取图片
             textView.text=firut.name//获取文字
         }
        return view
    }
}
复制代码

优化convertView将之前加载好的布局缓存

          val view:View
        if (convertView==null){
            view=LayoutInflater.from(context).inflate(resourceId,parent,false)
        }else{
            view=convertView
        }
复制代码

inner class()

inner class()
复制代码

RecyclerView

第一步在build gradle下添加

implementation 'androidx.recyclerview:recyclerview:1.0.0'
复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>


</LinearLayout>
复制代码
//自定义适配器
package com.example.recyclerview

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class FriutAdpater(val friutList: List<Fruit>):
    RecyclerView.Adapter<FriutAdpater.ViewHolder>(){
    //内部类,这个view一般是子项的最外层布局
    inner class ViewHolder(view: View):RecyclerView.ViewHolder(view){
        val fruitImageView:ImageView=view.findViewById(R.id.fruitImage)
        val fruitName:TextView=view.findViewById(R.id.fruitName)
    }
    //用与创建ViewHolder实例,将fruit_item布局加载进来
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
       val view=LayoutInflater.from(parent.context)
           .inflate(R.layout.fruit_item,parent,false)
        return  ViewHolder(view)
    }
    //告诉一共有多少子项
    override fun getItemCount()=friutList.size
   //用与对子项的数据进行赋值,position获取当前项的Fruit实例
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val fruit=friutList[position]
       holder.fruitImageView.setImageResource(fruit.imageId)
       holder.fruitName.text=fruit.name
    }
}
复制代码
    initFruit()//初始化水果数据
     //创建LinearLayoutManager实例
        val layoutManager=LinearLayoutManager(this)
        val recyclerView:RecyclerView=findViewById(R.id.recyclerview)
        //线性布局
        recyclerView.layoutManager=layoutManager
        val adaper=FriutAdpater(fruitList)
        recyclerView.adapter=adaper
复制代码
文章分类
Android
文章标签