系列
Fragment (一):Fragment使用详解
Fragment (二):Activity 和Fragment 的异常销毁、状态保存和恢复机制
Fragment (三):源码解析Fragment 返回栈原理
步骤:
1、继承Fragment,重写onCreateView()决定Fragemnt的布局。
2、在activity的xml中使用fragment标签加入该类,就当和普通的View一样。
activity的xml文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/id_fragment_title"
android:name="com.zhy.zhy_fragments.TitleFragment"
android:layout_width="fill_parent"
android:layout_height="45dp" />
<fragment
android:layout_below="@id/id_fragment_title"
android:id="@+id/id_fragment_content"
android:name="com.zhy.zhy_fragments.ContentFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
RelativeLayout>
‹fragment› 标签中的 android:name 属性指定要在布局中实例化的 Fragment 类。
每个Fragment都需要一个唯一的标识符,重启 Activity 时,系统可以使用该标识符来恢复Fragment(也可以使用该标识符来捕获Fragment以执行某些事务,如将其删除)。 可以通过三种方式为Fragment提供 ID:
为 android:id 属性提供唯一 ID
为 android:tag 属性提供唯一字符串
如果未给以上两个属性提供值,系统会使用容器视图的 ID
通过编程方式将Fragment添加到某个现有 ViewGroup 。
在activity中:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentA fragment = new FragmentA();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
概念
A Fragment is a piece of an application’s user interface or behavior that can be placed in an Activity. Interaction with fragments is done through FragmentManager, which can be obtained via Activity.getFragmentManager() and Fragment.getFragmentManager().
Fragment 表示 Activity 中的部分行为或UI。Fragment拥有自己的生命周期,但其生命周期受它所在Activity影响。Fragment有自己的Fragment返回栈。
Fragment的生命周期(其 Activity 运行时)。
Activity 生命周期对Fragment生命周期的影响。
可以看到Fragment比Activity多了几个额外的生命周期回调方法:
Activity 生命周期与Fragment生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。
Fragment返回栈:存放的是Fragment事务,栈顶事务出栈实质上就是对该事务进行逆操作。
Fragment返回栈与Activity返回栈区别与联系:
区别:默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈(以便用户通过“返回” 按钮回退到Activity)。不过,Fragment只有在Fragment的事务执行期间通过调用 addToBackStack() 显式请求保存实例时,系统才会将Fragment事务放入由宿主 Activity 管理的Fragment返回栈。栈顶元素出栈时,Activity返回栈是直接将栈顶的Activity显示到屏幕而Fragment返回栈则要先对栈顶的事务进行逆操作,并将操作结果显示在屏幕上。
联系:两者都是返回栈,栈顶“元素”出栈时删除屏幕上原来的“元素”并将栈顶元素显示在屏幕上做为前台“元素”。都可以通过按返回键实现出栈操作。
注意:前台“元素”(即当前屏幕上显示的“元素”)是不在返回栈中的。
概念:
要想管理Activity中的Fragment,需要使用FragmentManager。FragmentManager用于管理被添加的Fragment。
获取FragmentManager:
调用Activity或被添加的Fragment的getFragmentManager() // v4中,getSupportFragmentManager()。若是在FragmentA中添加FragmentB则须在FragmentA中通过getChildFragmentManager()获取。
注意:FragmentManager只管理它的直接子结点。通过调用Activity或被添加的Fragment的getFragmentManager() 获得的是管理该Activity下所有被添加的Fragment(不包括这些Fragment中的子Fragment)。通过调用FragmentA的getChildFragmentManager()获取的是管理FragmentA下所有被添加的Fragment(不包括这些Fragment中的子Fragment)。树形结构:Activity就是根,所有active fragment(“前台”fragment 和返回栈中的fragment)都是子结点。每个结点都持有FragmentManager,用于管理它的直接子结点。
“前台”fragment:调用了add()但既没有被销毁也尚未被移到返回栈中的fragment 。
FragmentManagerImpl 中有两个重要的Field:
- mAdded:fragment列表,保存所有前台fragment 。
- mActive:fragment列表,保存所有前台fragment 和返回栈中的fragment ,实际上就是active fragment。
无论是Activity还是Fragment,View状态想要实现自动保存,View必须设置了id。此外,textview还需要声明android:freezeText=”true”才能保存和恢复状态。
在Fragment 中引发状态保存和恢复有两种情形:
1. 异常销毁。
2. 事务进出返回栈。
1、异常销毁
Activity的异常销毁会导致它所管理的所有active fragment 的异常销毁。fragment的异常销毁会触发自身的onSaveInstanceState(),同时还会自动保存View 状态。
异常销毁发生后,用户再次回到该Activity会重建该Activity,同时之前的所有active fragment 也会被重建,在此过程中会自动恢复Fragment 的View状态,同时,用户可在onCreate() 或onActivityCreated() 中恢复Fragment 状态。
注意:异常销毁时Activity会被销毁,用户回到该Activity时,系统除了会自动重建该Activity,还会自动重建销毁前的 active fragment ,但其他Activity 持有的fragment 不会被自动重建。这些重建的fragment 全部都是show 状态。
2、事务进出栈
Fragment事务进入Fragment返回栈会自动保存进入返回栈的Fragment的View状态(注:在这一过程中不会调用onSaveInstanceState()),出栈时会自动恢复View状态。
更详细的介绍参考:Activity 、Fragment 的异常销毁、状态保存和恢复机制
参考:Android Fragment 真正的完全解析(下)
参考:Android Fragment 真正的完全解析(下)
在Activity中,已拥有FragmentA,若开启FragmentB时为兼容大屏幕必须:
参考:fragment 状态保存和恢复
本文参考:Fragment 用法总结(一)