您的位置:首页 > 其它

Fragment 操作原理

2016-02-26 01:40 190 查看

Fragment 操作原理

1.FragmentActivity.getSupportFragmentManager()

[code]//FragmentActivity.java
final FragmentManagerImpl mFragments = new FragmentManagerImpl();

public FragmentManager getSupportFragmentManager() {
    return mFragments;
}


FragmentActivity 的 fragmentManager 就是 FragmentManagerImpl 对象

2.FragmentManager.beginTransaction()

[code]//FragmentManagerImpl.java
@Override
public FragmentTransaction beginTransaction() {
    return new BackStackRecord(this);
}


开始事务就是创建一个 BackStackRecord 对象,该对象用来表示一个fragment事务

3.FragmentTransaction.add()

[code]//BackStackRecord.java
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
    doAddOp(containerViewId, fragment, tag, OP_ADD);
    return this;
}

private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
    fragment.mFragmentManager = mManager;

    if (tag != null) {
        ...
        fragment.mTag = tag;
    }

    if (containerViewId != 0) {
        ...
        fragment.mContainerId = fragment.mFragmentId = containerViewId;
    }

    //新建一个 Op,添加到队列中
    Op op = new Op();
    op.cmd = opcmd;
    op.fragment = fragment;
    addOp(op);
}

//添加 Op 到链表中
void addOp(Op op) {
    if (mHead == null) {
        mHead = mTail = op;
    } else {
        op.prev = mTail;
        mTail.next = op;
        mTail = op;
    }
    ...
    mNumOp++;
}


添加 Fragment 就是给 fragment 事务对象中Op对象链表中添加一个Op对象

4.FragmentTransaction.commit()

[code]public int commit() {
    return commitInternal(false);
}

int commitInternal(boolean allowStateLoss) {
    ...
    //添加 transaction 到 manager 的队列中
    mManager.enqueueAction(this, allowStateLoss);
    return mIndex;
}


提交事务就是把事务对象添加到 FragmentManager 队列中

5.FragmentManagerImpl.enqueueAction()

[code]public void enqueueAction(Runnable action, boolean allowStateLoss) {

    synchronized (this) {
        ...
        if (mPendingActions == null) {
            mPendingActions = new ArrayList<Runnable>();
        }
        mPendingActions.add(action);
        if (mPendingActions.size() == 1) {
            mActivity.mHandler.removeCallbacks(mExecCommit);
            mActivity.mHandler.post(mExecCommit);
        }
    }
}

Runnable mExecCommit = new Runnable() {
    @Override
    public void run() {
        execPendingActions();
}

/**
 * Only call from main thread!
 */
public boolean execPendingActions() {
    ...
    while (true) {
        int numActions;

        synchronized (this) {
            ...
            numActions = mPendingActions.size();
            if (mTmpActions == null || mTmpActions.length < numActions) {
                mTmpActions = new Runnable[numActions];
            }
            mPendingActions.toArray(mTmpActions);
            mPendingActions.clear();
            mActivity.mHandler.removeCallbacks(mExecCommit);
        }

        mExecutingActions = true;
        for (int i=0; i<numActions; i++) {
            //执行 pendding 中的 action.run,就是执行事务
            mTmpActions[i].run();
            mTmpActions[i] = null;
        }
        ...
    }

    ...
    return didSomething;
}


6.BackStackRecord.run()

[code]public void run() {
    ...
    bumpBackStackNesting(1);

    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);
                        ...
                                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;

        }

        op = op.next;
    }

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

    if (mAddToBackStack) {
        mManager.addBackStackState(this);
    }
}


调用 FragmentManager 中的 add、remove、show、hide 等方法,replace 方法是移除 mManager.mAdded 中的 fragment

7.FragmentManager.add()

[code]public void addFragment(Fragment fragment, boolean moveToStateNow) {
    if (mAdded == null) {
        mAdded = new ArrayList<Fragment>();
    }
    if (DEBUG) Log.v(TAG, "add: " + fragment);
    makeActive(fragment);
    if (!fragment.mDetached) {
        if (mAdded.contains(fragment)) {
            throw new IllegalStateException("Fragment already added: " + fragment);
        }
        //添加到 mAddded 集合中
        mAdded.add(fragment);
        fragment.mAdded = true;
        fragment.mRemoving = false;
        if (fragment.mHasMenu && fragment.mMenuVisible) {
            mNeedMenuInvalidate = true;
        }
        if (moveToStateNow) {
            moveToState(fragment);
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: