Fragment 是怎样与 Activity 联系起来的?

2019-05-27  本文已影响0人  plusw

代码实现:

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又两种方式:

  1. 直接在Layout的xml文件中添加Fragment的视图
  2. 通过代码添加

第一种方式很简单,但是缺乏灵活性。第二种复杂,但是很灵活。一般首选第二种。

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 事务:

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 一起销毁的。

上一篇 下一篇

猜你喜欢

热点阅读