Fragment执行流程分析,2021春招BAT面试真题详解

}

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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值