Android开发 - Activity笔记

第一行代码:Android 学习笔记

Activity

3.2 Activity的基本用法

  1. Activity

    • 一个app可以有多个activity
    • activity位于app/src/main/java/com.xxx.xxx,是kotlin文件
  2. Activity的Layout(布局)

    • 逻辑和视图分离,视图用layout
    • 一个activity对应一个layout
    • layout在app/src/main/res/layout
    • layout有LinearLayout,RelativeLayout等多种布局形式
    • layout是xml文件
    • 在activity(Kotlin)的onCreate 函数中加入setContentView(R.layout.xxxx) 为activity加载布局
  3. Activity中的元素

    • layout中可以有Button,TextView等元素

    • 元素的多种属性(在layout文件中,属于布局的样式)

      • android:id="@+id/id_name" 元素的名字
      • android:layout_width/height="10dp"/"wrap_content"
        1. "10dp" 是直接写出长度,单位有dp,sp,px等
        2. "wrap_content" 是适合当前内容长度
        3. "match_parent" 是和父元素一样宽
      • android:text 显示的内容
    • 元素的事件(在activity文件中,属于与元素交互的逻辑)

      • 首先findViewById ,将布局文件中的元素在Kotlin代码中声明val button1 :Button = findViewById(R.id.button1)
      • 按钮的点击button1.setOnClickListener { ... }
      • Toast底部通知
        • Toast.makeText(this, "...", Toast.LENGTH_SHORT).show()

        • ...为通知的内容

        • 先通过makeText() 构建 一个新的Toast对象,之后调用show()将其显示

        • 第三个参数有默认的Toast.LENGTH_SHORTToast.LENGTH_LONG两种

          val button1 :Button = findViewById(R.id.button1)
          button1.setOnClickListener {
              Toast.makeText(this, "You click it!", Toast.LENGTH_SHORT).show()
          }
          
  4. AndroidManifest 文件

    • 位于app/src/main/AndroidManifest.xml
    • 所有activity在此注册,新建activity时AS会自动注册
    • 可修改如下activity的属性
      • name 代码中的名字
      • label运行时在顶栏显示的文字,主activity的label 还是应用程序显示的名称
      • 是否是主activity <intent-filter>
      • action,category,data
    <activity
        android:name=".FirstActivity"
        android:label="This is FirstActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  5. Activity中的Menu

    • menu在app/src/main/res/menu

    • 为menu添加item,属于视图部分(xml)。menu中的两个item如下图添加

        <menu xmlns:android="http://schemas.android.com/apk/res/android">
            <item
                android:id="@+id/add_item"
                android:title="Add"
                />
            <item
                android:id="@+id/remove_them"
                android:title="Remove" />
        </menu>
      
    • 重写onCreateOptionsMenu()函数(可以使用Ctrl+O快捷键)

      override fun onCreateOptionsMenu(menu: Menu?): Boolean {
          menuInflater.inflate(R.menu.main, menu)
          return true
      }
      
      • menuInflater是通过调用父类的getMenuInflater获得,属于Kotlin的”语法糖“
      • inflater接受两个参数,第一个是通过哪个文件来创建菜单,第二个是添加到哪一个菜单中
      • 返回值为true时,创建的菜单才能显示
    • 重写onOptionsItemSelected()函数

      override fun onOptionsItemSelected(item: MenuItem): Boolean {
          when (item.itemId) {
              R.id.add_item -> Toast.makeText(this, "Add!", Toast.LENGTH_SHORT).show()
              R.id.remove_them -> Toast.makeText(this, "Remove!", Toast.LENGTH_SHORT).show()
          }
          return true
      }
      
      • 对应的id出现对应的通知

3.3 使用Intent切换Activity

  1. 显式intent

    button1.setOnClickListener {
        val intent = Intent(this, SecondActivity::class.java)
        startActivity(intent)
    }
    
    • (假设要启动的activity叫SecondActivity
    • 先以要启动activity的名字__构建__一个intent对象
    • 调用函数startActivity启动activity
  2. 隐式intent

    button1.setOnClickListener {
        val intent = Intent("com.example.firstcode.ACTION_START")
        intent.addCategory("com.example.firstcode.MY_CATEGORY")
        startActivity(intent)
    }
    
    • 以action构建一个intent对象,可以实现这个action的activity将会被启动
    • 之后使用添加category的函数addCategory,有同时满足两个条件的activity才会启动,否则程序崩溃
  3. 使用隐式intent调用浏览器,电话

    • 调用浏览器

      button1.setOnClickListener {
          val intent = Intent(Intent.ACTION_VIEW)
          intent.data = Uri.parse("https://www.baidu.com")
          startActivity(intent)
      }
      
      • Intent.ACTION_VIEW是浏览器的action,等于"android.intent.action.VIEW"
      • Uri.parse()将字符串转为data
      • AndroidManifest.xml中可以为activity添加action,category,data
      • data可以配置 <data android:scheme="https" /> https://xx.xx.xx.xx:xxxx/xxx/xxx/xxx
        1. android:scheme协议https
        2. android:host主机名xx.xx.xx.xx
        3. android:port端口:xxxx
        4. android:path路径/xxx/xxx/xxx
        5. android:mimetype可以处理的数据类型
    • 让一个activity以浏览器的形式被调用

      • 在AndroidManifest.xml对应的activity处加上<action android:name="android.intent.action.VIEW"
      • 系统会问你选哪个
    • 调用电话

      button1.setOnClickListener {
          val intent = Intent(Intent.ACTION_DIAL)
          intent.data = Uri.parse("tel:10086")
          startActivity(intent)
      }
      
      • Intent.ACTION_DIAL是电话的action
      • Uri.parse将字符串转化为电话
  4. activity间传递数据

    • 向下一个activity传递数据

      • 前一个activity中

        button1.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            val data = "Hello SecondActivity"
            intent.putExtra("extra_data", data)
            startActivity(intent)
        }
        
        1. 使用putExtra函数在intent中添加数据
        2. 第一个参数是用于取值的键,第二个参数是数据
      • 后一个activity中

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_second)
            val extraData = intent.getStringExtra("extra_data")
            Log.d("Second_Activity", "extra data is $extraData")
            Toast.makeText(this, "$extraData", Toast.LENGTH_SHORT).show()
        }
        
        1. intent是调用父类的getIntent()
        2. 通过intent.getStringExtra("...")获得数据 ...是键
        3. 整数使用getIntExtra() ,布尔型使用getBooleanExtra()
    • 返回数据给上一个activity

      • 前一个activity中

        button1.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            val data = "Hello SecondActivity"
            intent.putExtra("extra_data", data)
            startActivityForResult(intent, 1)
        }
        
        1. 使用startActivityForResult(intent, 1)函数
          • 第二个参数为请求码,请求码是唯一值(为了区分调用的是哪个activity)
      • 后一个activity中(当按钮2用于结束activity时)(onBackPressed为按下返回键结束activity前执行)

        button2.setOnClickListener {
            val intent = Intent()
            intent.putExtra("data_return", "Hello FirstActivity")
            setResult(RESULT_OK, intent)
            finish()
        }
        
        override fun onBackPressed() {
            val intent = Intent()
            intent.putExtra("data_return", "Hello FirstActivity")
            setResult(RESULT_OK, intent)
            finish()
        }
        
        1. 创建一个intent但不用来调用activity只用来传递信息
        2. 使用setResult()函数
          • 第一个参数返回处理结果,RESULT_OKRESULT_CANCELED两种
          • 第二个参数通过intent返回数据
      • 又是前一个activity

        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
            when(requestCode) {
                1 -> if(resultCode == RESULT_OK) {
                    val returnedData = data?.getStringExtra("data_return")
                    Toast.makeText(this, "$returnedData", Toast.LENGTH_SHORT).show()
                    Log.d("FirstActivity", "returned data is $returnedData")
                }
            }
        }
        
        1. 后一个activity销毁后调用onActivityResult
        2. requestCode 从前一个activity中来,是请求码
        3. resultCode从后一个activity中来,是后一个activity的能否返回数据的处理结果
        4. data是用于返回数据的intent

3.4 Activity的生命周期

  1. activity使用返回栈管理
  2. activity有多种状态
    • 运行 位于栈顶
    • 暂停 不位于栈顶但可见
    • 停止 不位于栈顶且不可见
    • 销毁 从返回栈中移除
  3. 函数
    • onCreate() onDestory() 创建和销毁时调用
    • onStart() onStop() 在不可见和可见切换时调用
    • onResume() onPause() 在是不是栈顶时调用
    • onRestart() 在停止变成运行时调用 onStop()->onRestart()->onStart()
  4. 在activity被回收之前保存数据
    • 在被回收前一定会调用onSaveInstanceState()函数
    • 在这个函数携带的Bundle类型的参数中putString()
    • onCreate()函数的Bundle类型的参数中重新取出数据

3.5 Activity的启动模式

在AndroidManifest中修改

  1. standard 可以有很多的相同的activity
  2. singleTop 栈顶只能有一个相同的activity
  3. singleTask 总共只能有一个相同的activity
  4. singleInstance 为当前activity创造一个新的栈 /- /-

3.6 Activity的技巧

  1. 构建BaseActivity类,在其中输出调试信息,并让所有activity都继承于BaseActivity类,可以让每个activity都打印调试信息
  2. 构建单例类,每次onCreate() / onDestory()调用,用ArrayList记录,可以随时调用函数将所有activity结束
  3. 在每个activity中构建类静态函数actionStart,在其中构建intent并添加数据,之后调用当前activity。这样做可以使被调用activity需要的数据传递更清晰。

3.7 Kotlin 课堂

  1. 标准函数with run apply

    val xxx = with(obj) {
    	a()
        b()
        c()
    	d()   // 最后一个是赋给xxx的值
    }
    
    ==
    
    val xxx = obj.run {
    	a()
        b()
        c()
    	d()   // 最后一个是赋给xxx的值
    }
    
    ==
    
    val temp = obj.apply {
    	a()
        b()
        c()
    }
    val xxx = temp.d()
    
    ==
    
    val temp = obj
    obj.a()
    obj.b()
    obj.c()
    val xxx = temp.d()
    
  2. 静态方法

    class Util {
    	companion object {
    		fun doAction {
                ...
    		}
    	}
    }
    
    • 可以直接调用Util.doAction(),但是并非真正静态办法,在Java中无法使用
    • companion object内部加入@JvmStatic可以编译成真正的静态方法,Java中也可以使用
posted @ 2021-01-07 16:10  Sleepp  阅读(35)  评论(0编辑  收藏  举报