栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Fragment执行流程分析,最新阿里Android高级面试题及答案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Fragment执行流程分析,最新阿里Android高级面试题及答案

  • 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;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667331.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号