Fragment执行流程分析

  • 效果

在这里插入图片描述

add方式添加Fragment

  • 使用方式
		// 加载第一个Fragment V4包  兼容11以下的版本
        FragmentManager fragmentManager = getSupportFragmentManager();
        // 开启事物
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        // 把第一个Fragment HomeFragment加载进来
        mHomeFragment = new HomeFragment();
        // 第一个参数是Fragment的容器id,需要添加的Fragment
        fragmentTransaction.add(R.id.main_tab_fl, mHomeFragment);
        // 一定要commit
        fragmentTransaction.commit();
  • add(int contianerId,Fragment); 方式

    private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
        final Class fragmentClass = fragment.getClass();
        final int modifiers = fragmentClass.getModifiers();
        if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers)
                || (fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers))) {
            throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
                    + " must be a public static class to be  properly recreated from"
                    + " instance state.");
        }

        fragment.mFragmentManager = mManager;

        if (tag != null) {
            if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
                throw new IllegalStateException("Can't change tag of fragment "
                        + fragment + ": was " + fragment.mTag
                        + " now " + tag);
            }
            fragment.mTag = tag;
        }

        if (containerViewId != 0) {
            if (containerViewId == View.NO_ID) {
                throw new IllegalArgumentException("Can't add fragment "
                        + fragment + " with tag " + tag + " to container view with no id");
            }
            if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
                throw new IllegalStateException("Can't change container ID of fragment "
                        + fragment + ": was " + fragment.mFragmentId
                        + " now " + containerViewId);
            }
            fragment.mContainerId = fragment.mFragmentId = containerViewId;
        }

        addOp(new Op(opcmd, fragment));
    }

add()方法实际上就是对设置进行封装,真正的添加是在commit()方法时执行

  • commit()提交流程

在这里插入图片描述

replace()方式添加Fragment

		// 加载第一个Fragment V4包  兼容11以下的版本
        FragmentManager fragmentManager = getSupportFragmentManager();
        // 开启事物
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        // 把第一个Fragment HomeFragment加载进来
        mHomeFragment = new HomeFragment();
        // 第一个参数是Fragment的容器id,需要添加的Fragment
        fragmentTransaction.replace(R.id.main_tab_fl, mHomeFragment);
        // 一定要commit
        fragmentTransaction.commit();

replace()和add()同样调用的是doAddOp()方法,只是opcmd不一样

 @Override
    public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
        doAddOp(containerViewId, fragment, tag, OP_ADD);
        return this;
    }
@Override
    public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
        if (containerViewId == 0) {
            throw new IllegalArgumentException("Must use non-zero containerViewId");
        }

        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
        return this;
    }
  • OP_ADD
 switch (op.cmd) {
                case OP_ADD:
                case OP_ATTACH:
                    added.add(op.fragment);
                    break;
                case OP_REMOVE:
                case OP_DETACH: {
                    added.remove(op.fragment);
                    if (op.fragment == oldPrimaryNav) {
                        mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment));
                        opNum++;
                        oldPrimaryNav = null;
                    }
                }

可以看到OP_ADD直接执行的是added.add(op.fragment);添加操作

  • OP_REPLACE
  case OP_REPLACE: {
                    final Fragment f = op.fragment;
                    final int containerId = f.mContainerId;
                    boolean alreadyAdded = false;
                    for (int i = added.size() - 1; i >= 0; i--) {
                        final Fragment old = added.get(i);
                        if (old.mContainerId == containerId) {
                            if (old == f) {
                                alreadyAdded = true;
                            } else {
                                // This is duplicated from above since we only make
                                // a single pass for expanding ops. Unset any outgoing primary nav.
                                if (old == oldPrimaryNav) {
                                    mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
                                    opNum++;
                                    oldPrimaryNav = null;
                                }
                                final Op removeOp = new Op(OP_REMOVE, old);
                                removeOp.enterAnim = op.enterAnim;
                                removeOp.popEnterAnim = op.popEnterAnim;
                                removeOp.exitAnim = op.exitAnim;
                                removeOp.popExitAnim = op.popExitAnim;
                                mOps.add(opNum, removeOp);
                                added.remove(old);
                                opNum++;
                            }
                        }
                    }
                    if (alreadyAdded) {
                        mOps.remove(opNum);
                        opNum--;
                    } else {
                        op.cmd = OP_ADD;
                        added.add(f);
                    }

OP_REPLACE首先吧cmd变成OP_REMOVE,然后执行的是added.remove(old);操作,然后执行 added.add(f);CMD变为OP_ADD

void executeOps() {
        final int numOps = mOps.size();
        for (int opNum = 0; opNum < numOps; opNum++) {
            final Op op = mOps.get(opNum);
            final Fragment f = op.fragment;
            if (f != null) {
                f.setNextTransition(mTransition, mTransitionStyle);
            }
            switch (op.cmd) {
                case OP_ADD:
                    f.setNextAnim(op.enterAnim);
                    mManager.addFragment(f, false);
                    break;
                case OP_REMOVE:
                    f.setNextAnim(op.exitAnim);
                    mManager.removeFragment(f);
                    break;
                case OP_HIDE:
                    f.setNextAnim(op.exitAnim);
                    mManager.hideFragment(f);
                    break;
                case OP_SHOW:
                    f.setNextAnim(op.enterAnim);
                    mManager.showFragment(f);
                    break;
                case OP_DETACH:
                    f.setNextAnim(op.exitAnim);
                    mManager.detachFragment(f);
                    break;
                case OP_ATTACH:
                    f.setNextAnim(op.enterAnim);
                    mManager.attachFragment(f);
                    break;
                case OP_SET_PRIMARY_NAV:
                    mManager.setPrimaryNavigationFragment(f);
                    break;
                case OP_UNSET_PRIMARY_NAV:
                    mManager.setPrimaryNavigationFragment(null);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
            }
            if (!mReorderingAllowed && op.cmd != OP_ADD && f != null) {
                mManager.moveFragmentToExpectedState(f);
            }
        }
        if (!mReorderingAllowed) {
            // Added fragments are added at the end to comply with prior behavior.
            mManager.moveToState(mManager.mCurState, true);
        }
    }
执行的是 mManager.removeFragment(f);

removeFragment()会把上一个Fragment移除

mManager.addFragment(f, false);

addFragment() 会把新的Fragment添加到容器中

replace()的源码就是把之前的移除,会重新执行Fragment生命周期, 会重新绘制界面

封装工具类

package com.qufu.fragmentdemo.helper;

import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import java.util.List;

public class FragmentManagerHelper {
    private FragmentManager mFragmentManager;
    private int mContainerViewId;

    /**
     * 构造函数
     *
     * @param fragmentManager 管理类FragmentManager
     * @param containerViewId 容器布局id containerViewId
     */
    public FragmentManagerHelper(@Nullable FragmentManager fragmentManager, @IdRes int containerViewId) {
        this.mFragmentManager = fragmentManager;
        this.mContainerViewId = containerViewId;
    }

    /**
     * 添加Fragment
     */
    public void add(Fragment fragment) {
        // 开启事物
        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
        // 第一个参数是Fragment的容器id,需要添加的Fragment
        fragmentTransaction.add(mContainerViewId, fragment);
        // 一定要commit
        fragmentTransaction.commit();
    }

    /**
     * 切换显示Fragment
     */
    public void switchFragment(Fragment fragment) {
        // 开启事物
        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

        // 1.先隐藏当前所有的Fragment
        List<Fragment> childFragments = mFragmentManager.getFragments();
        for (Fragment childFragment : childFragments) {
            fragmentTransaction.hide(childFragment);
        }

        // 2.如果容器里面没有我们就添加,否则显示
        if (!childFragments.contains(fragment)) {
            fragmentTransaction.add(mContainerViewId, fragment);
        } else {
            fragmentTransaction.show(fragment);
        }
        // 一定要commit
        fragmentTransaction.commit();
    }
}
  • 使用案例
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;

import com.qufu.fragmentdemo.helper.FragmentManagerHelper;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {


    private BottomNavigationView mNavigation;
    private FragmentManagerHelper mFragmentManagerHelper;
    private ArrayList<Fragment> fragments = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFragmentManagerHelper = new FragmentManagerHelper(getSupportFragmentManager(), R.id.fl_main);
        fragments.add(OneFragment.newInstance());
        fragments.add(TwoFragment.newInstance());
        fragments.add(ThreeFragment.newInstance());
        fragments.add(FourFragment.newInstance());
        mFragmentManagerHelper.add(fragments.get(0));
        initView();
        initListener();

    }

    @SuppressLint("NewApi")
    private void initView() {
        mNavigation = (BottomNavigationView) findViewById(R.id.navigation);
    }

    private void initListener() {
        mNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.navigation_home:
                        mFragmentManagerHelper.switchFragment(fragments.get(0));
                        return true;
                    case R.id.navigation_fun:
                        mFragmentManagerHelper.switchFragment(fragments.get(1));
                        return true;
                    case R.id.navigation_income:
                        mFragmentManagerHelper.switchFragment(fragments.get(2));
                        return true;
                    case R.id.navigation_notifications:
                        mFragmentManagerHelper.switchFragment(fragments.get(3));
                        return true;
                }
                return false;
            }
        });
    }


}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,Fragment 是一种可以嵌入到 Activity 中的可重用组件。当 Activity 运行时,Fragment 可以独立地添加、移除、替换和交互。下面是 Fragment 的执行过程: 1. 创建 Fragment 对象:通过调用 Fragment 的构造函数来创建一个新的 Fragment 对象。 2. 添加 Fragment 到 Activity:使用 FragmentManager 将 Fragment 添加到对应的 Activity。 3. 为 Fragment 创建视图:在 Fragment 的生命周期方法 onCreateView() 中创建和返回视图层次结构。 4. 绑定 Fragment 到 Activity:在 Fragment 的生命周期方法 onAttach() 中将 Fragment 绑定到它的父 Activity。 5. 创建 Fragment:在 Fragment 的生命周期方法 onCreate() 中进行初始化工作,例如恢复保存的状态、初始化变量等。 6. 创建 Activity 视图:在 Activity 的生命周期方法 onCreateView() 中创建 Activity 的视图层次结构。 7. 把 Fragment 加入到 Activity 视图:将 Fragment 在 Activity 视图中占据的位置预留给它,可以使用 <fragment> 标签或者动态添加。 8. 可见性改变:在 Fragment 的生命周期方法 onStart() 中,Fragment 变为可见状态,可以与用户交互。 9. 焦点获取:在 Fragment 的生命周期方法 onResume() 中,Fragment 获取焦点,可以响应用户输入。 10. 用户交互:Fragment 可以通过用户输入(点击按钮、触摸屏幕等)响应用户交互,处理用户交互事件。 11. 生命周期变化:当 Activity 的生命周期发生变化时,Fragment 的生命周期也会随之变化。 12. 可见性改变:在 Fragment 的生命周期方法 onPause() 中,Fragment 失去焦点,不再与用户交互。 13. 保存状态:在 Fragment 的生命周期方法 onSaveInstanceState() 中,保存 Fragment 的状态。 14. 不可见性改变:在 Fragment 的生命周期方法 onStop() 中,Fragment 变为不可见状态。 15. 解绑 Fragment:在 Fragment 的生命周期方法 onDetach() 中,将 Fragment 与它的父 Activity 解绑。 16. 销毁 Fragment:在 Fragment 的生命周期方法 onDestroy() 中,释放资源,销毁 Fragment 对象。 这是一个典型的 Fragment 生命周期流程,每个生命周期方法都提供了对应的回调函数,我们可以在这些方法中执行相应的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值