}
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() {
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
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 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 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;