本文介绍: 一个Activity中,在某一个器中更换不同的Fragment,从而显示不同的界面这个场景相信大家已经非常熟悉了,也知道Activity通过FragmentManager管理嵌入的Fragments的,所以今天就来看看FragmentManager如何工作的。当添加完一系列动作后,操作没有生效我们需要调用commit或者commitNow来提交事务,才能看到最终的结果。这了出现了一个HostCallbacks继承自FragmentHostCallback看看它的初始化

一个Activity中,在某一个容器中,更换不同的Fragment,从而显示不同的界面,这个场景相信大家已经非常熟悉了,也知道Activity通过FragmentManager管理嵌入的Fragments的,所以今天就来看看FragmentManager如何工作的。

我们继承AppCompatActivity分析

我们常用的几种操作大致如下

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment f1 = new Fragment();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(f1,"tag");
transaction.hide(f1);
transaction.show(f1);
transaction.replace(R.id.layout1,f1);
transaction.remove(f1);

首先我们要获得FragmentManager对象实例

FragmentManager fragmentManager = getSupportFragmentManager();

那我们就看看getSupportFragmentManager干了什么

FragmentActivity.class

    @NonNull
    public FragmentManager getSupportFragmentManager() {
        return this.mFragments.getSupportFragmentManager();
    }

mFragments是 FragmentController 实例声明时直接初始化final对象

final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

这了出现了一个HostCallbacks继承自FragmentHostCallback看看它的初始化

public HostCallbacks() {
    super(FragmentActivity.this);
}

基类构造如下:
    FragmentHostCallback(@NonNull FragmentActivity activity) {
        this(activity, activity, new Handler(), 0);
    }

    FragmentHostCallback(@Nullable Activity activity, @NonNull Context context, @NonNull Handler handler, int windowAnimations) {
//实际执行操作的是FragmentManagerImpl实例
        this.mFragmentManager = new FragmentManagerImpl();
        this.mActivity = activity;
        this.mContext = (Context)Preconditions.checkNotNull(context, "context == null");
//handler,后面会用到
        this.mHandler = (Handler)Preconditions.checkNotNull(handler, "handler == null");
        this.mWindowAnimations = windowAnimations;
    }

重点是FragmentManagerImpl,具体的操作都交给了FragmentManagerImpl对象

再回到FragmentController.createController,通过传递HostCallbacks参数,将对属性mHost赋值

    private FragmentController(FragmentHostCallback<?> callbacks) {
        this.mHost = callbacks;
    }

这样的话,FragmentController mFragments初始化完成。回过头来再看getSupportFragmentManager的过程

//FragmentActivity.class

    public FragmentManager getSupportFragmentManager() {
        //调用FragmentController的getSupportFragmentManager
        return this.mFragments.getSupportFragmentManager();
    }

//FragmentController.class

    @NonNull
    public FragmentManager getSupportFragmentManager() {
        //返回mHost(FragmentHostCallback)中的FragmentManagerImpl对象
        return this.mHost.mFragmentManager;
    }

所以下面这句话拿到的就是FragmentManagerImpl实例

FragmentManager fragmentManager = getSupportFragmentManager();

拿到fragmengManager后,接着开启一个事务FragmentTransaction。

FragmentTransaction transaction = fragmentManager.beginTransaction();

调用下面接口

//FragmentManagerImpl.class

    @NonNull
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

 我们看到了一个新的类BackStackRecord,看名字大概是回退栈的意思,它继承自FragmentTransaction,它记录了Fragment的索引信息,每次beginTransaction都会产生一个BackStackRecord对象,BackStackRecord中持有了当前FragmentManagerImpl对象,操作Fragment的动作,都是由这里入口,然后调用基类FragmentTransaction的方法,将每个动作都添加到Op对象中,比如下面:

transaction.hide
//BackStackRecord.java

    @NonNull
    @Override
    public FragmentTransaction hide(@NonNull Fragment fragment) {
        if (fragment.mFragmentManager != null &amp;& fragment.mFragmentManager != mManager) {
            throw new IllegalStateException("Cannot hide Fragment attached to "
                    + "a different FragmentManager. Fragment " + fragment.toString() + " is already"
                    + " attached to a FragmentManager.");
        }
        return super.hide(fragment);
    }

//FragmentTransaction.java

    @NonNull
    public FragmentTransaction hide(@NonNull Fragment fragment) {
        //添加Op到操作列表中
        addOp(new Op(OP_HIDE, fragment));

        return this;
    }

当添加完一系列的动作后,操作并没有生效,我们需要调用commit或者commitNow来提交事务,才能看到最终的结果

commit不会立即执行,它会把事务放在队列里,会在线程下一次执行时进行操作。

//commit调用commitInternal

    int commitInternal(boolean allowStateLoss) {
        ......
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }

commitNow会立即执行事务

//commitNow会调用FragmentManagerImpl的execSingleAction

    @Override
    public void commitNow() {
        disallowAddToBackStack();
        mManager.execSingleAction(this, false);
    }

这样整个FragmentManager就开始工作了,后面我们会想想讲解每一种操作的具体源码

原文地址:https://blog.csdn.net/bdmh/article/details/134648136

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_30826.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注