- 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;
public FragmentManagerHelper(@Nullable FragmentManager fragmentManager, @IdRes int containerViewId) {
this.mFragmentManager = fragmentManager;
this
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
.mContainerViewId = containerViewId;
}
public void add(Fragment fragment) {
// 开启事物
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
// 第一个参数是Fragment的容器id,需要添加的Fragment
fragmentTransaction.add(mContainerViewId, fragment);
// 一定要commit
fragmentTransaction.commit();
}
public void switchFragment(Fragment fragment) {
// 开启事物
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
// 1.先隐藏当前所有的Fragment
List 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;



