最新Androidx Fragment的前世今生系列(二)之Fragment的生命周期
背景
Fragment依赖于Activity,它的生命周期也与Activity息息相关,下面这张来自官网的图,可以很好的说明这个问题,但是对于我们上一篇文章提到的两种添加Fragment的方式(静态添加和动态添加)而言,这其中Fragement与Activity生命周期的具体表现又略有不同,后面我们会结合具体的例子详细说明。
Fragment生命周期概述
函数 | 描述 |
---|---|
onAttach() | 将Fragment与宿主的Activity关联起来 |
onCreate() | 创建Fragment |
onCreateView() | 创建Fragment视图 |
onActivityCreated() | 宿主Activity被创建 |
onStart() | Fragment变得可见 |
onResume() | Fragment可交互 |
onPause() | Fragment可见但不可交互 |
onStop() | Fragment不可见 |
onDestroyView() | 销毁Fragment视图 |
onDestroy() | 清除Fragment的状态 |
onDetach() | 解除Fragment与Activity绑定 |
实验一:以静态方式添加Fragment
MainActivity布局如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_one"
android:layout_width="match_parent"
android:layout_weight="1"
android:name="com.snow.fragmentdemo.FragmentOne"
android:layout_height="match_parent">
</fragment>
<fragment
android:id="@+id/fragment_two"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.snow.fragmentdemo.FragmentTwo">
</fragment>
</LinearLayout>
</FrameLayout>
效果如图
当我们打开app,生命周期函数执行顺序如图
从图中我们可以看到首先宿主Activity开始创建,但是在还未创建成功时就已经与FragmentOne绑定,然后FragmentOne开始创建,创建视图,然后Activity创建完成,然后调用onViewStateRestored(Bundle)方法存储FragmentOne的状态信息,然后FragmentOne可见,最后可交互。
当我们按回退建,回退出这个Activity,生命周期函数执行顺序入如图
从图中我们可以看出,当按下回退建,FragmentOne和Activity开始变得不可交互,不可见,然后FragmentOne销毁视图,清除状态,与Activity解除绑定,最后Activity销毁。
实验2:动态加入Fragment
关键代码如下
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TEST","Activity creating");
setContentView(R.layout.activity_main2);
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.content, new FragmentOne());
//transaction.addToBackStack(null);
transaction.commit();
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
}
@Override
public void onClick(View v) {
FragmentManager fm = getSupportFragmentManager();
switch (v.getId()) {
case R.id.button1:
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.content, new FragmentOne());
transaction.addToBackStack(null);
transaction.commit();
break;
case R.id.button2:
FragmentTransaction transaction2 = fm.beginTransaction();
transaction2.replace(R.id.content, new FragmentTwo()).addToBackStack(null).commit();
break;
}
}
效果如图
中间是一个FrameLayout,下面时两个按钮可以对Fragment进行切换,我将FragmentOne设置为了打开默认加载的Fragment,当我们打开app,生命周期函数执行顺序如下图
可以看到开始与静态加入是一样的,当我们点击two,跳转到FragmentTwo,结果如下
由于我们没有使用transaction.addToBackStack(null),所以FragmentOne直接被销毁了然后与Activity解除绑定。而且我们如果按下回退见,会直接退出Activity。当我们使用transaction.addToBackStack(null)时,前面的文章已经说过transaction.addToBackStack(null)让我们的操作入栈,可以回滚。点击跳转FragmentTwo结果如下
我们可以看到FragmentOne并没有被销毁,只是销毁了视图。因为视图销毁了,所以页面的内容也销毁了,那么如果我们使用add方法添加FragmentTwo,结果会是如何,如下图所示
我们可以看到,FragmentOne生命周期并未变化,视图也没被销毁。所以如果需要保留页面内容,可以选择add方法来替换Fragment,由于也调用了transaction.addToBackStack(null),当我们按下回退键就回到前一个Fragment,而且如果页面有editText,里面的内容不会消失。
相关文章
最新Androidx Fragment的前世今生系列(一)之Fragment的简单使用
最新Androidx Fragment的前世今生系列(二)之Fragment的生命周期
最新Androidx Fragment的前世今生系列(三)之Fragment与Acivity的通信
最后
transaction.addToBackStack(null)是相对于add等操作而言的,如果进行一系列操作之后调用transaction.addToBackStack(null)然后提交,当你按下回退建,就相当于将那些操作取消,回到操作前的状态。点赞就是最大的支持,更多学习资料可以关注公众号QStack, 追求最纯粹的技术,享受编程的快乐。