这是我参与「第四届青训营 」笔记创作活动的第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基本用法
- 注册:在AndroidManifest.xml中注册
- 布局:在layout中配置布局文件
- 绑定:将布局绑定到Activity
Activity生命周期
前面提到Activity具有程序入口的功能,Android程序启动时总遵从一定的顺序去调用MainActivity的一些成员函数来完成程序的初始化、界面的加载等等任务并最终将界面呈现在用户面前,最后关闭程序。Activity从创建到最终销毁全过程的函数调用顺序就是Activity的生命周期,系统在Activity生命周期的不同阶段调用不同的函数,所以Android开发者必须了解Activity的生命周期,程序才能在预期的时候做出预期的行为。
下图展示了在Activity生命周期不同阶段系统的行为:
+-------------+
+-----------> | 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生命周期流转:
- 在配置发生改变时(例如:屏幕发生旋转,显示方向由竖屏变为横屏),将会调用
onConfigurationChanged()方法,可以通过对该方法的重写实现一些特殊功能。在通常情况下,配置发生改变将引起Activty的重建,重建的函数调用过程如下所述:- 销毁:Resumed -> onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> Destroyed
- 重建:Destroyed -> onCteate() -> onStart() -> onRestoreInstanceState() -> onResume() -> Resumed
- 可以通过配置AndroidManifest中的configChange属性来实现不重建Activity
- 启动:onCreate() -> onStart() -> onResume() -> Resumed
- 退出:Resumed -> onPause() -> onStop() -> onDestroy() -> Destroyed
- 部分覆盖:Resumed -> onPause() -> Paused
- 部分遮挡恢复:Paused -> onResume() -> Resumed
- 完全覆盖:Resumed -> onPause() -> onSaveInstanceState() -> onStop() -> Stoped
- 完全遮挡恢复:Stoped -> onStart() -> onResume() -> Resumed
- 后台回收:Stoped -> Killed
- 回收恢复: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基本用法
- 创建Fragment布局文件
- 创建Fragment子类,在适当函数中加载布局文件
- Activity加载Fragment
- 静态加载
- 在Activity的onCreate()函数中声明Fragment
- 或在Activity的布局文件中声明Fragment
- 动态加载
- 使用Fragment Manager进行加载
- 静态加载
Fragment生命周期
如下所示:
一些常见场景中的Fragment生命周期流转:
- 启动:onAttach() -> onCreate() -> onCreateView() -> onActivityCreated() -> onStart() -> onResume() -> Resumed
- 退出:Resumed -> onPause() -> onStop() -> onDestoryView() -> onDestory() -> Destroyed
- 部分覆盖:Resumed -> onPause() -> Paused
- 部分遮挡恢复:Paused -> onResume() -> Resumed
- 完全覆盖:Resumed -> onPause() -> onSaveInstanceState() -> onStop() -> Stoped
- 完全遮挡恢复:Stoped -> onStart() -> onResume() -> Resumed
- 后台回收:Stoped -> Killed
- 回收恢复:Killed -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume() -> Resumed
此外,Fragment生命周期也可以通过FragmentTransaction.setMaxLifecycle()进行手动干预
Fragment与Activity的交互
-
组件获取
- Fragment获取Activity中的组件:
getActivity().findViewById(id) - Activity获取Fragment中的组件:
getFragmentManager.findFragmentById(id)
- Fragment获取Activity中的组件:
-
数据传递
- Activity传数据给Fragment:
setArguments(bundle) - Fragment传数据给Activity:
- 通过对象(
getActivity())直接传递(方法调用/接口调用) - 通过viewmodel/handler/broadcast/eventbus等通信
- 通过对象(
- Activity传数据给Fragment: