Fragment 生命周期
Fragment 生命周期的11个方法: onAttach()
, onCreate()
, onCreateView()
, onActivityCreated()
, onStart()
, onResume()
, onPause()
, onStop()
, onDestoryView()
, onDestory()
, onDetach()
Fragment 的生命周期和Activity 很相似,只是多了一下方法:
onAttach(): 在Fragment 和Activity 建立关联时调用(Activity 传递到此方法内)
onCreateView(): 当Fragment 创建视图时调用
onActivityCreated(): 在相关联的Activity 的onCreate() 方法已经返回时调用
onDestory(): 当Fragment 中的视图被移除时调用
onDetach(): 当Fragment 和Activity 取消关联时调用
举例说明几种情况下Fragment 生命周期的变化
- 打开界面:
onCreate() -> onCreateView() -> onActivityCreated() -> onStart() -> onResume()
-
按下主屏幕键
onPause() -> onStop()
-
重新打开页面
onStart() -> onResume()
-
按后退键
onPause() -> onStop() -> onDestoryView() -> onDestory() - onDetach()
管理Fragment 的生命周期和Activity 生命周期很相似,同时Activity 的生命周期对Fragment 的生命周期也有一定的影响,如下图所示:
用下图(来源)来表示 Activity 和 Fragment 的生命周期变化的先后过程是:
加载Fragment
加载Fragment 有两种方式:静态加载
和 动态加载
:
静态加载:
静态加载在Activity 的布局文件中声明即可, 例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
其中Fragment 中的 android:name
要指定Fragment 对应的包名路径,当系统创建此Activity 布局时,会实例化在布局中指定的每个Fragment, 并为每个Fragment 调用 onCreateView()
方法,以检索每个Fragment 的布局。系统会直接插入Fragment 返回的View 来代替Fragment 元素;
并且在Activity 中可以直接使用findViewById()
方法获取Fragment 对应布局中的控件。同样在Fragment 中可以直接使用 getActivity()
方法获得绑定的主Activity 实例,并调用Activity 里的方法或其他Fragment 实例。
动态加载:
通过Java (或kotlin)代码将Fragment 添加到某个Activity 布局中现有的 ViewGroup
(例如 LinearLayout
或 FrameLayout
)里。
要想在Activity 中执行Fragment 事务(如添加、删除或替换Fragment),必须使用FragmentTransaction
中的API。可以使用下面实例从Activity 中获取一个FragmentTransaction
:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
然后使用add()
方法添加一个Fragment, 指定要添加的Fragment 要插入到哪个视图。例如:
ExampleFragment exampleFragment = new ExampleFragment();
fragmentTransaction.add(R.id.frame_layout,exampleFragment);
fragmentTransaction.commit();
add()
方法中第一个参数是一个Activity 中对应布局文件中的ViewGroup
,即应该放置Fragment 的位置,由资源 ID 指定,第二个参数是加入的Fragment ,一旦提供FragmentTransaction
做了更改,最后必须使用commit()
方法使更改生效。
添加没有UI 的Fragment:
以上展示了向Activity 中添加Fragment 以显示UI,不过,还可使用Fragment 为Activity 提供后台行为,而不显示额外UI。
要想添加没有UI 的片段,请使用add(Fragment, String)
从Activity 添加片段(为片段提供一个唯一的字符串“标记”,而不是视图 ID)。由于它并不与Activity 布局中的相关视图关联,所有不会收到对onCreateView()
的调用。因此不用实现该方法。
执行Fragment 事务
在Activity 中使用Fragment 可以很方便的进行添加(add)、替换 (replace)、移除(remove) 等操作,这样提供给Activity 的每组更改都称为事务。像上面动态添加Fragment,使用FragmentTransaction
中的API 就可以执行一项事务。同时也可以将此事务保存到Activity 管理的返回栈中,从而用户可以回退到Fragment 之前的状态(实现类似Activity 回退到上一个页面)
一下代码举例展示如何替换一个 fragment,并把替换之前的状态保存到 Activity 的返回栈中:
Fragment newFragment = new ExampleFragment();
FragmentTransaction mTransaction = getFragmentManager().beginTransaction();
//用新的 fragment 替换原来fragment 所在位置的布局,并且把此事务添加到返回栈中。
mTransaction.replace(R.id.frame_layout,newFragment);
mTransaction.addToBackStack(null);
mTransaction.commit();
如果在执行移除Fragment 的事务时没有调用addToBackStack()
,则事务提交时该Fragment 会被销毁,用户将无法回退到该Fragment。不过,在删除Fragment 时调用了addToBackStack()
,则系统会停止该Fragment, 并在用户按返回键时将其恢复。
Fragment 与 Activity 通信
Fragment 中可以调用getActivity()
获取Activity 的实例并调用Activity 中的方法和布局,同样在Activity 中也可以通过 findViewById()
(对于在Activity 提供Fragment 布局的)或者findFragmentByTag()
(对于在Activity 提供或者不提供Fragment 布局的)方法获取Fragment 的实例,例如在Activity 中从Fragment 的引用来调用Fragment 中的方法:
Fragment fragment = getFragmentManager.findFragmentById(R.id.fragment_container);
使用FragmentManger 还可以执行的操作:
- 通过
findFragmentById()
或findFragmentByTag()
获取Activity 中存在的实例; - 通过
popBackStack()
(模拟用户点击返回按钮操作) 将Fragment 从返回栈中弹出; - 通过
addOnBackChangedListener()
注册一个监听返回栈改变的监听器; - 通过以上生成 fragmentTransaction 的方法,可以使用 fragmentManager 生成一个 fragmentTransaction 来执行某些事务,比如添加、替换、移除、addToBackStack()等。