XJL's Blog

保持乐观、单纯。 要开心。

爱家人朋友,爱猫咪,爱学习。


Fragment 生命周期

Fragment 生命周期的11个方法: onAttach(), onCreate(), onCreateView(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestoryView(), onDestory(), onDetach()

Fragment Lifecycle

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 生命周期对片段生命周期的影响

用下图(来源)来表示 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 (例如 LinearLayoutFrameLayout )里。

要想在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()等。
最近的文章

Service 相关知识学习笔记

Service 基础Service 的分类:按运行地点分类:本地服务和远程服务;按运行类型分类:前台服务和后台服务;按功能分类:可通信服务和不可通信服务特点:按运行地点分类: 类别 特点 优点 缺点 应用场景 本地服务(LocalService) 1,运行在主线程2, 主线程被终止后,服务也会被终止。 1, 节约资源2, 通信方便:由于在同一进程中因此不需要IPC1和AIDL...…

继续阅读
更早的文章

Broadcast 广播相关知识学习笔记

Broadcast 的定义Broadcast 是Android 中广泛应用在应用程序之间传输信息的机制。发送的广播是一个Intent,这个Intent可以携带我们想要的数据。不同应用程序之间只要注册了和发送广播相同的action 的广播接收者,都可以收到这个广播。广播的使用场景 同一App 中多个进程的不同组件之间的消息通信 不同App 的组件之间通信广播的种类 **普通广播:Context.sendBroadcast: **传给各个符合条件的receiver ,各个receiver...…

继续阅读