代码实现:
public abstract class SingleFragmentActivity extends AppCompatActivity {
protected abstract Fragment createFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}
}
}
Activity托管Fragment又两种方式:
- 直接在Layout的xml文件中添加Fragment的视图
- 通过代码添加
第一种方式很简单,但是缺乏灵活性。第二种复杂,但是很灵活。一般首选第二种。
1. 创建容器视图
容器视图是Fragment的容器,是一种通用的视图,不限于为特定的Fragment提供容器:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
2. 创建Fragment视图
这个就根据业务需要自己定义就行了。需要什么组件就放上去。
3. 在 Activity 中向 FragmentManager 添加 Fragment
FragmentManager 负责管理 Fragment 并把它们的视图添加到 Activity 的视图层级中。
FragmentManager 具体管理:
- fragment 队列
- fragment 事务回退栈
下面这段代码创建了并提交一个 Fragment 事务:
if (fragment == null) {
fragment = new CrimeFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
fragment 事务被用来添加,移除, 附加,分离或替换 Fragment 队列中的 Fragment。这是使用 Fragment 动态组装和重新组装用户界面的关键。
FragmentManager 维护这一个Fragment队列,经过上面的代码,我们的Fragment 对象就被添加到队列当中了,并且用容器的资源ID R.id.fragment_container
作为队列中该Fragment的唯一标识。所以如果要向Activity 中添加多个 Fragment需要分别为每个 Fragment 创建有不同ID的不同容器。
正如上面所说,容器的资源ID是 Fragment 在队列中的唯一标识,所以在取出 Fragment的时候,也是传入容器的ID:
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
4. FragmentManager 与 Fragment 生命周期
再来看一下完整的 Activity 托管 Fragment 的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}
}
在 onCreate() 方法中并不是每次都创建新的 Fragment 实例,而是先尝试去 FragmentManager 维护的队列中取 Fragment 对象。为什么队列中可能有 Fragment 对象呢?
Activity 销毁时会调用 onDestroy(), 但是 FragmentManager 不会被销毁,而且它会保存 Fragment 队列。也就是说 FragmentManager 不是随着 Activity 一起销毁的。