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,再添加到容器上。

results matching ""

    No results matching ""