Fragment add、remove、delete、show、hide源代码阅读

 Fragment add 、remove 、replace、show、hide原理
FragmentManager  FragmentTransaction FragmentManagerImpl
BackStackRecord
(1)Activity的getFragmentManager()方法
public FragmentManager getFragmentManager() {
return mFragments;
}
其中mFragments为
final FragmentManagerImpl mFragments = new FragmentManagerImpl();
(2)FragmentManagerImpl extends FragmentManager,看下它的beginTransaction()方法
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
其中BackStackRecord extends FragmentTransaction implements Runnable
(3)看下BackStackRecord的add方法
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
其中doAddOp中主要是调用封装Op并调用addOp方法
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
(4)看下BackStackRecord的addOp方法
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
是加入到一个循环链表中
(5)看下BackStackRecord的commit方法
public int commit() {
return commitInternal(false);
}
和commitInternal方法
int commitInternal(boolean allowStateLoss) {
if (mCommitted) {
throw new IllegalStateException("commit already called");
}
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
PrintWriter pw = new FastPrintWriter(logw, false, 1024);
dump(" ", null, pw, null);
pw.flush();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
执行FragmentManagerImpl的enqueueAction
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mActivity == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<Runnable>();
}
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
mActivity.mHandler.removeCallbacks(mExecCommit);
mActivity.mHandler.post(mExecCommit);
}
}
}
直接插入到UI线程中执行或者在FragmentManagerImpl的execPendingActions()中执行。
(6)还记得BackStackRecord implements Runnable,它执行是在run()方法中
public void run() {
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Run: " + this);
}

if (mAddToBackStack) {
if (mIndex < 0) {
throw new IllegalStateException("addToBackStack() called after commit()");
}
}

bumpBackStackNesting(1);

SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
calculateFragments(firstOutFragments, lastInFragments);
beginTransition(firstOutFragments, lastInFragments, false);

Op op = mHead;
while (op != null) {
switch (op.cmd) {
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
}
break;
case OP_REPLACE: {
Fragment f = op.fragment;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
if (f == null || old.mContainerId == f.mContainerId) {
if (old == f) {
op.fragment = f = null;
} else {
if (op.removed == null) {
op.removed = new ArrayList<Fragment>();
}
op.removed.add(old);
old.mNextAnim = op.exitAnim;
if (mAddToBackStack) {
old.mBackStackNesting += 1;
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Bump nesting of "
+ old + " to " + old.mBackStackNesting);
}
}
mManager.removeFragment(old, mTransition, mTransitionStyle);
}
}
}
}
if (f != null) {
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
}
}
break;
case OP_REMOVE: {
Fragment f = op.fragment;
f.mNextAnim = op.exitAnim;
mManager.removeFragment(f, mTransition, mTransitionStyle);
}
break;
case OP_HIDE: {
Fragment f = op.fragment;
f.mNextAnim = op.exitAnim;
mManager.hideFragment(f, mTransition, mTransitionStyle);
}
break;
case OP_SHOW: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.showFragment(f, mTransition, mTransitionStyle);
}
break;
case OP_DETACH: {
Fragment f = op.fragment;
f.mNextAnim = op.exitAnim;
mManager.detachFragment(f, mTransition, mTransitionStyle);
}
break;
case OP_ATTACH: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.attachFragment(f, mTransition, mTransitionStyle);
}
break;
default: {
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
}

op = op.next;
}

mManager.moveToState(mManager.mCurState, mTransition,
mTransitionStyle, true);

if (mAddToBackStack) {
mManager.addBackStackState(this);
}
}
具体仍然是调用FramentManagerImpl的对应方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中,可以通过 hide() 和 show() 方法来切换 Fragment。具体的实现步骤如下: 1. 获取 FragmentManager 对象: ```java FragmentManager fragmentManager = getSupportFragmentManager(); ``` 2. 开启一个 FragmentTransaction 事务: ```java FragmentTransaction transaction = fragmentManager.beginTransaction(); ``` 3. 如果要切换到的 Fragment 还没有被添加到 Activity 中,则使用 add() 方法添加到容器中: ```java transaction.add(R.id.container, newFragment); ``` 4. 如果已经添加过,可以使用 show() 方法显示该 Fragment: ```java transaction.show(newFragment); ``` 5. 使用 hide() 方法隐藏当前的 Fragment: ```java transaction.hide(currentFragment); ``` 6. 最后,提交事务: ```java transaction.commit(); ``` 完整的示例代码如下: ```java // 获取 FragmentManager 对象 FragmentManager fragmentManager = getSupportFragmentManager(); // 开启一个 FragmentTransaction 事务 FragmentTransaction transaction = fragmentManager.beginTransaction(); // 如果要切换到的 Fragment 还没有被添加到 Activity 中,则添加到容器中 if (!newFragment.isAdded()) { transaction.add(R.id.container, newFragment); } // 隐藏当前的 Fragment transaction.hide(currentFragment); // 显示要切换到的 Fragment transaction.show(newFragment); // 提交事务 transaction.commit(); ``` 注意,这里的 currentFragment 和 newFragment 都是 Fragment 对象,需要根据具体的情况进行替换。同时,R.id.container 是一个 FrameLayout 容器,用来承载 Fragment

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值