fragment的跳转方式
- 同一个activity中的fragment之间跳转
- 从当前fragemnt跳转到另一个activity
- 从activity跳转到其他的activity/fragment
- 从当前activity的fragemnt跳转到另一个activity的指定fragemnt上
同一个activity中的fragment之间跳转
只要在activity上覆盖上fragemnt即可,或者直接替换掉。
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.xx, new XxxFragment(), null)
.addToBackStack(null)
.commit();
replace和add的差别
FragmentController
是对应fragment依附的activity的管理器,它管理了一些activity的一些关键节点的回调,从而完成activity和fragemnt之间的交互。
FragmentTransaction
相当于fragment操作数据的收集,为了后面manager方便的操作;它是个抽象类,具体的实现类是BackStackRecord
。
FragmentManager
是fragment实际操作的抽闲类,它的具体实现是FragmentManagerImpl
。
对fragment的操作就是通过这4个类完成的。
beginTransaction
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
这个主要就是为了创建自己的fragemnt的事务对象,以便后面的操作。
add
@Override
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
replace
@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;
}
可以看出,add和replace后面的逻辑都是一样的,只是通过操作的类型进行区分。
doAddOp
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
...
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
}
void addOp(Op op) {
mOps.add(op);
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
}
addOp只是维护了一个数组的列表,将操作存储起来。
commitXX
int commitInternal(boolean allowStateLoss) {
...
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
FragemntManager#enqueueAction
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);
scheduleCommit();
}
}
FragemntManager#execPendingActions
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
doPendingDeferredStart();
return didSomething;
}
FragemntManager#optimizeAndExecuteOps
从当前fragemnt跳转到另一个activity
从fragemnt跳转到activity上的操作跟正常的跳转是类似的,只是传入的参数区别:
Intent intent = new Intent(getActivity(),OtherActivity.class);
startActivity(intent);
从activity跳转到其他的activity/fragment
Intent intent = new Intent(OtherActivity.this, MainActivity.class);
startActivity(intent);
从当前activity的fragemnt跳转到另一个activity的指定fragemnt上
核心代码上跟上面的类似,都是startActivity,不同的是,需要再跳转到activity上的时候,主动的去切换fragemnt。
目前是这样处理的:
就是讲fragment传给activity,让它自己去构建fragemnt,再添加到容器上。