Android界面容器介绍 | 青训营笔记

238 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第2天。

界面组件有界面容器,也有TextView、Button等界面元素,这里来介绍界面容器。

界面容器承担着为界面提供容器的重要作用,我们打开任何一个App,都会看到程序界面,界面中包括各种各样的文字、按钮、图形等等元素;而有时通过一些操作,又会打开新的界面(例如:在聊天软件中点击某人头像,打开与ta的私聊界面;又例如:相册总览界面、大图页面和图片编辑页面就是三个不同的界面)。用户通过界面与程序进行交互,,而界面容器为界面提供了容身之地,可见界面容器在Android开发中的重要性。

下面介绍Activity和Fragment两种界面容器。

Activity

Activity是Android系统中最基础的界面容器,它承担着前台交互、程序入口和布局容器的功能。前台交互,也就是用户直接通过Activity提供的界面与程序进行交互;与通常C/C++命令行程序从main函数开始运行不同,Android程序总是从MainActivity中的成员函数开始运行,所以Activity承担了程序入口的功能;此外,Android中若干UI组件(例如文本TextView、图片ImageView、按钮Button等)的位置依赖于布局,而Activity充当着布局容器的角色。

Activity基本用法

  1. 注册:在AndroidManifest.xml中注册
  2. 布局:在layout中配置布局文件
  3. 绑定:将布局绑定到Activity

Activity生命周期

前面提到Activity具有程序入口的功能,Android程序启动时总遵从一定的顺序去调用MainActivity的一些成员函数来完成程序的初始化、界面的加载等等任务并最终将界面呈现在用户面前,最后关闭程序。Activity从创建到最终销毁全过程的函数调用顺序就是Activity的生命周期,系统在Activity生命周期的不同阶段调用不同的函数,所以Android开发者必须了解Activity的生命周期,程序才能在预期的时候做出预期的行为。

下图展示了在Activity生命周期不同阶段系统的行为:

activity_lc.png

                                 +-------------+
                   +-----------> |   Started   +-------> onResume() <-------------+
                   |             +-------------+            |                     |
                   |                    ^                   |                     |
               onStart()                |                   v                     |
                   ^                    |               +---------+               |
                   |                    |               | Resumed |               |
                   |                    |               +---+-----+               |
                   |                 onStart()              |                 +---+----+
             +-----+-----+              ^                   +--->onPaused()-->| Paused |
onCreate()-->|  Created  |              |                                     +---+----+
             +-----------+              |             +---------+                 |
                                     onRestart()<-----+ Stopped |<------onStop()<-+
                                                      +----+----+
                     +-----------+                         |
                     | Destroyed |<------- onDestroy() <---+
                     +-----------+
  • onCreate() 在Activity创建时被调用,通常在这里创建视图、绑定数据
  • onStart() 即将进入前台
  • onResume() 与用户进行交互
  • onPause() 被其他Activity部分覆盖,Activiy部分可见时被调用
  • onStop() 被其他Activity完全覆盖,Activiy不可见时被调用
  • onRestart() 重启已经Stop的Activity时被调用
  • onDestroy() Activity被销毁时被调用,用于释放Activity占用的所有资源
  • onSaveInstanceState() 在非正常关闭时被调用,用于保存运行数据
  • onRestoreInstanceState() 用于恢复保存的数据

总而言之,Activity总是在Active、Pause、Stop和Killed四种状态之间转换,当它被创建并和用户交互时,处于Active状态;当它失去焦点时,处于Pause或Stop状态;当它被销毁后,处于Killed状态。

一些常见场景中的Activity生命周期流转:

  1. 在配置发生改变时(例如:屏幕发生旋转,显示方向由竖屏变为横屏),将会调用onConfigurationChanged()方法,可以通过对该方法的重写实现一些特殊功能。在通常情况下,配置发生改变将引起Activty的重建,重建的函数调用过程如下所述:
    • 销毁:Resumed -> onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> Destroyed
    • 重建:Destroyed -> onCteate() -> onStart() -> onRestoreInstanceState() -> onResume() -> Resumed
    • 可以通过配置AndroidManifest中的configChange属性来实现不重建Activity
  2. 启动:onCreate() -> onStart() -> onResume() -> Resumed
  3. 退出:Resumed -> onPause() -> onStop() -> onDestroy() -> Destroyed
  4. 部分覆盖:Resumed -> onPause() -> Paused
  5. 部分遮挡恢复:Paused -> onResume() -> Resumed
  6. 完全覆盖:Resumed -> onPause() -> onSaveInstanceState() -> onStop() -> Stoped
  7. 完全遮挡恢复:Stoped -> onStart() -> onResume() -> Resumed
  8. 后台回收:Stoped -> Killed
  9. 回收恢复:Killed -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume() -> Resumed

Activity启动模式

Activity具有4种启动模式,分别是Standard、SingleTop、SingleTask和SingleInstance。

  • Standard
    • 这种启动模式允许Activity重复,这也是默认的启动模式
  • SingleTop
    • 这种启动模式不允许Activity与栈顶Activity重复,也就是不允许连续的重复Activity
  • SingleTask
    • 这种启动模式不允许同一栈内Activity有重复,如果要启动的Activity已在栈内,将会从栈中移除该Activity之上的所有Activity
  • SingleInstance
    • 这种启动模式不允许全局有重复的Activity

Fragment

Fragment是Android系统为解决屏幕尺寸碎片化问题而提供的一种轻量级页面容器。

Fragment基本用法

  1. 创建Fragment布局文件
  2. 创建Fragment子类,在适当函数中加载布局文件
  3. Activity加载Fragment
    1. 静态加载
      • 在Activity的onCreate()函数中声明Fragment
      • 或在Activity的布局文件中声明Fragment
    2. 动态加载
      • 使用Fragment Manager进行加载

Fragment生命周期

如下所示:

fragment_lc.png

一些常见场景中的Fragment生命周期流转:

  1. 启动:onAttach() -> onCreate() -> onCreateView() -> onActivityCreated() -> onStart() -> onResume() -> Resumed
  2. 退出:Resumed -> onPause() -> onStop() -> onDestoryView() -> onDestory() -> Destroyed
  3. 部分覆盖:Resumed -> onPause() -> Paused
  4. 部分遮挡恢复:Paused -> onResume() -> Resumed
  5. 完全覆盖:Resumed -> onPause() -> onSaveInstanceState() -> onStop() -> Stoped
  6. 完全遮挡恢复:Stoped -> onStart() -> onResume() -> Resumed
  7. 后台回收:Stoped -> Killed
  8. 回收恢复:Killed -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume() -> Resumed

此外,Fragment生命周期也可以通过FragmentTransaction.setMaxLifecycle()进行手动干预

Fragment与Activity的交互

  • 组件获取

    • Fragment获取Activity中的组件:getActivity().findViewById(id)
    • Activity获取Fragment中的组件:getFragmentManager.findFragmentById(id)
  • 数据传递

    • Activity传数据给Fragment:setArguments(bundle)
    • Fragment传数据给Activity:
      • 通过对象(getActivity())直接传递(方法调用/接口调用)
      • 通过viewmodel/handler/broadcast/eventbus等通信