您的位置:首页 > 其它

Fragment加载过程分析。

2014-07-24 10:35 477 查看
Fragment加载到屏幕上的代码非常简单。getFragmentManager().beginTransaction().add(int addId,Fragment addFragment,String tag).commit();
首先看getFragmentMananger()方法:它定义在Activity中:

public FragmentManager getFragmentManager() {
        return mFragments;
    }


它只是直接返回了成员变量mFragments。这个变量的类型是FragmentManagerImpl.它是FragmentManager的子类。与FragmentManager和FragmentManagerState处于同一个文件中。而FragmentManager实际上是一个抽象类。

接着看第二个。beginTransaction():

public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
}


它将此FragmentManager本身赋给了一个叫做BackStackRecord的类。并将此Manager的实例在内部用一个成员变量保存起来。用于做回退栈栈管理之类的操作。故名思义。这是用于做Fragment回退栈记录处理的类。接着往下看add方法。这个方法是定义在BackStackRecord类中。

public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
    doAddOp(containerViewId, fragment, tag, OP_ADD);
    return this;
}


这个方法里面直接将成员变量交给一个叫做doAddOp的方法进行处理。再多传了一个标志位。用于区分add、remove、replace等操作:

private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) { 
        fragment.mFragmentManager = mManager; 
  if (tag != null) { 
            if (fragment.mTag != null && !tag.equals(fragment.mTag)) { 
                throw new IllegalStateException("Can't change tag of fragment " 
                        + fragment + ": was " + fragment.mTag 
                        + " now " + tag); 
            } 
            fragment.mTag = tag; 
        } 
 if (containerViewId != 0) { 
            if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) { 
                throw new IllegalStateException("Can't change container ID of fragment " 
                        + fragment + ": was " + fragment.mFragmentId 
                        + " now " + containerViewId); 
            } 
            fragment.mContainerId = fragment.mFragmentId = containerViewId; 
        } 
 Op op = new Op(); 
        op.cmd = opcmd; 
        op.fragment = fragment; 
        addOp(op); 
 }


这个方法中进行了一些保护性的判断。并将containerViewId和tag赋给要添加的fragment.并将此fragment放于一个Op的容器类中。类似我们常用的ViewHolder。它定义在BackStackRecord类中。而在add方法中传过来的参数OP_ADD。将它保存在了op类中的cmd变量中。

static final class Op { 
        Op next; 
        Op prev; 
        int cmd; 
        Fragment fragment; 
        int enterAnim; 
        int exitAnim; 
        int popEnterAnim; 
        int popExitAnim; 
        ArrayList<Fragment> removed; 
}


接着看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++; 
 }


这个方法就是把封装了此fragment的op实例保存起来。并将设置的动画也加入其中。

到此add方法算是介绍完了。接下来是commit方法,它也是在BackStackRecord类中定义。

public int commit() { 
        return commitInternal(false); 
}


此处直接调用类中的commitInternal方法。传一个false进入。而我们知道fragment提交时还有一个叫做commitAllowingStateLoss的方法。这个方法内部也是直接调用commitInternal方法。但是传入一个true进入:

int commitInternal(boolean allowStateLoss) { 
        if (mCommitted) throw new IllegalStateException("commit already called"); 
        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); 
        mCommitted = true; 
        if (mAddToBackStack) { 
            mIndex = mManager.allocBackStackIndex(this); 
        } else { 
            mIndex = -1; 
        } 
        mManager.enqueueAction(this, allowStateLoss); 
        return mIndex; 
 }


这个方法中将对此fragment进行入栈操作。使用FragmentManagerImpl对象的enqueueAction方法将将回退栈记录管理类传回去。
下面回到FragmentManagerImpl类中:

public void enqueueAction(Runnable action, boolean allowStateLoss) { 
        if (!allowStateLoss) { 
            checkStateLoss(); 
        } 
        synchronized (this) { 
            if (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); 
            } 
        } 
 }


allowStateLoss就是当时commitInternal传入的变量。在commit时为false。在commitAllowingStateLoss时为true。所以。在为false时。会调用checkStateLoss来检查状态。接着用了一个同步锁。在里面将BackStackRecord实例装入了mPendingActions的数组中。BackStackRecord是Runnable的子类。再将mExecCommit加入到主线程的handler中进行处理。这也是我们可以连续使用add、replace等在同一条语句的原因。在mExecCommit的Runnable对象中。调用了execPendingActions方法。

public boolean execPendingActions() { 
        if (mExecutingActions) { 
            throw new IllegalStateException("Recursive entry to executePendingTransactions"); 
        } 
         
        if (Looper.myLooper() != mActivity.mHandler.getLooper()) { 
            throw new IllegalStateException("Must be called from main thread of process"); 
        } 
  boolean didSomething = false;
  while (true) {
            int numActions; 
             
            synchronized (this) { 
                if (mPendingActions == null || mPendingActions.size() == 0) { 
                    break; 
                } 
                 
                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++) { 
                mTmpActions[i].run(); 
                mTmpActions[i] = null; 
            } 
            mExecutingActions = false; 
            didSomething = true; 
        } 
 if (mHavePendingDeferredStart) {
            boolean loadersRunning = false; 
            for (int i=0; i<mActive.size(); i++) { 
                Fragment f = mActive.get(i); 
                if (f != null && f.mLoaderManager != null) { 
                    loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 
                } 
            } 
            if (!loadersRunning) { 
                mHavePendingDeferredStart = false; 
                startPendingDeferredFragments(); 
            } 
        } 
        return didSomething; 
 }


这个方法中用了一个while(true)循环对mPendingActions进行操作。所以接着看mPendingActions里面的Runnable对象的run方法。而这个里面保存的是BackStackRecord对象。所以又回到BackStackRecord类中:

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


可以看见。在run方法中。它也进行了一个while(true)循环。在里面从Op中一个个的通过next变量取出下一个Op实例。每个Op实例包装一个Fragment实例。方法内部用switch对不同的操作进行区别运行。此处我们看OP_ADD中的代码。它把Fragment实例和它的进行动画取出来。使用FragmentManager管理类addFragment。在addFragment方法中。此将Fragment加入了一个叫做mAdded的成员变量中。类型是ArrayList。范型是Fragment。代表已加入的fragment。然后跳出switch语句。执行FragmentManagerImpl中的moveToState方法。

void moveToState(int newState, int transit, int transitStyle, boolean always) {
        if (mActivity == null && newState != Fragment.INITIALIZING) {
            throw new IllegalStateException("No activity");
        }
       
        if (!always && mCurState == newState) {
            return;
        }
       
        mCurState = newState;
        if (mActive != null) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                if (f != null) {
                    moveToState(f, newState, transit, transitStyle, false);
                    if (f.mLoaderManager != null) {
                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                    }
                }
            }
            if (!loadersRunning) {
                startPendingDeferredFragments();
            }
            if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
                mActivity.invalidateOptionsMenu();
                mNeedMenuInvalidate = false;
            }
        }
    }


一般我们commit的地方在Activity的super.onCreate之后。此处newState为ACTIVITY_CREATED 。状态值总共有如下几个:
static final int INVALID_STATE = -1;   // Invalid state used as a null value.
    static final int INITIALIZING = 0;     // Not yet created.
    static final int CREATED = 1;          // Created.
    static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
    static final int STOPPED = 3;          // Fully created, not started.
    static final int STARTED = 4;          // Created and started, not resumed.
    static final int RESUMED = 5;          // Created started and resumed.


在此方法中。程序调用五个参数的moveToState

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
            boolean keepActive) {
        // Fragments that are not currently added will sit in the onCreate() state.
        if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
            newState = Fragment.CREATED;
        }
        if (f.mRemoving && newState > f.mState) {
            // While removing a fragment, we can't change it to a higher state.
            newState = f.mState;
        }
        // Defer start if requested; don't allow it to move to STARTED or higher
        // if it's not already started.
        if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
            newState = Fragment.STOPPED;
        }
        if (f.mState < newState) {
            // For fragments that are created from a layout, when restoring from
            // state we don't want to allow them to be created until they are
            // being reloaded from the layout.
            if (f.mFromLayout && !f.mInLayout) {
                return;
            }
            if (f.mAnimatingAway != null) {
                // The fragment is currently being animated... but! Now we
                // want to move our state back up. Give up on waiting for the
                // animation, move to whatever the final state should be once
                // the animation is done, and then we can proceed from there.
                f.mAnimatingAway = null;
                moveToState(f, f.mStateAfterAnimating, 0, 0, true);
            }
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
                    if (f.mSavedFragmentState != null) {
                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
                                FragmentManagerImpl.VIEW_STATE_TAG);
                        f.mTarget = getFragment(f.mSavedFragmentState,
                                FragmentManagerImpl.TARGET_STATE_TAG);
                        if (f.mTarget != null) {
                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
                        }
                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
                        if (!f.mUserVisibleHint) {
                            f.mDeferStart = true;
                            if (newState > Fragment.STOPPED) {
                                newState = Fragment.STOPPED;
                            }
                        }
                    }
                    f.mActivity = mActivity;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mActivity.mFragments;
                    f.mCalled = false;
                    f.onAttach(mActivity);
                    if (!f.mCalled) {
                        throw new SuperNotCalledException("Fragment " + f
                                + " did not call through to super.onAttach()");
                    }
                    if (f.mParentFragment == null) {
                        mActivity.onAttachFragment(f);
                    }
                    if (!f.mRetaining) {
                        f.performCreate(f.mSavedFragmentState);
                    }
                    f.mRetaining = false;
                    if (f.mFromLayout) {
                        // For fragments that are part of the content view
                        // layout, we need to instantiate the view immediately
                        // and the inflater will take care of adding it.
                        f.mView = f.performCreateView(f.getLayoutInflater(
                                f.mSavedFragmentState), null, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mInnerView = f.mView;
                            f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                            if (f.mHidden) f.mView.setVisibility(View.GONE);
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                        } else {
                            f.mInnerView = null;
                        }
                    }
                case Fragment.CREATED:
                    if (newState > Fragment.CREATED) {
                        if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                        if (!f.mFromLayout) {
                            ViewGroup container = null;
                            if (f.mContainerId != 0) {
                                container = (ViewGroup)mContainer.findViewById(f.mContainerId);
                                if (container == null && !f.mRestored) {
                                    throwException(new IllegalArgumentException(
                                            "No view found for id 0x"
                                            + Integer.toHexString(f.mContainerId) + " ("
                                            + f.getResources().getResourceName(f.mContainerId)
                                            + ") for fragment " + f));
                                }
                            }
                            f.mContainer = container;
                            f.mView = f.performCreateView(f.getLayoutInflater(
                                    f.mSavedFragmentState), container, f.mSavedFragmentState);
                            if (f.mView != null) {
                                f.mInnerView = f.mView;
                                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                                if (container != null) {
                                    Animation anim = loadAnimation(f, transit, true,
                                            transitionStyle);
                                    if (anim != null) {
                                        f.mView.startAnimation(anim);
                                    }
                                    container.addView(f.mView);
                                }
                                if (f.mHidden) f.mView.setVisibility(View.GONE);
                                f.onViewCreated(f.mView, f.mSavedFragmentState);
                            } else {
                                f.mInnerView = null;
                            }
                        }
                        f.performActivityCreated(f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.restoreViewState(f.mSavedFragmentState);
                        }
                        f.mSavedFragmentState = null;
                    }
                case Fragment.ACTIVITY_CREATED:
                case Fragment.STOPPED:
                    if (newState > Fragment.STOPPED) {
                        if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
                        f.performStart();
                    }
                case Fragment.STARTED:
                    if (newState > Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
                        f.mResumed = true;
                        f.performResume();
                        f.mSavedFragmentState = null;
                        f.mSavedViewState = null;
                    }
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
                        f.performPause();
                        f.mResumed = false;
                    }
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
                        f.performStop();
                    }
                case Fragment.STOPPED:
                    if (newState < Fragment.STOPPED) {
                        if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
                        f.performReallyStop();
                    }
                case Fragment.ACTIVITY_CREATED:
                    if (newState < Fragment.ACTIVITY_CREATED) {
                        if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
                        if (f.mView != null) {
                            // Need to save the current view state if not
                            // done already.
                            if (!mActivity.isFinishing() && f.mSavedViewState == null) {
                                saveFragmentViewState(f);
                            }
                        }
                        f.performDestroyView();
                        if (f.mView != null && f.mContainer != null) {
                            Animation anim = null;
                            if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
                                anim = loadAnimation(f, transit, false,
                                        transitionStyle);
                            }
                            if (anim != null) {
                                final Fragment fragment = f;
                                f.mAnimatingAway = f.mView;
                                f.mStateAfterAnimating = newState;
                                anim.setAnimationListener(new AnimationListener() {
                                    @Override
                                    public void onAnimationEnd(Animation animation) {
                                        if (fragment.mAnimatingAway != null) {
                                            fragment.mAnimatingAway = null;
                                            moveToState(fragment, fragment.mStateAfterAnimating,
                                                    0, 0, false);
                                        }
                                    }
                                    @Override
                                    public void onAnimationRepeat(Animation animation) {
                                    }
                                    @Override
                                    public void onAnimationStart(Animation animation) {
                                    }
                                });
                                f.mView.startAnimation(anim);
                            }
                            f.mContainer.removeView(f.mView);
                        }
                        f.mContainer = null;
                        f.mView = null;
                        f.mInnerView = null;
                    }
                case Fragment.CREATED:
                    if (newState < Fragment.CREATED) {
                        if (mDestroyed) {
                            if (f.mAnimatingAway != null) {
                                // The fragment's containing activity is
                                // being destroyed, but this fragment is
                                // currently animating away. Stop the
                                // animation right now -- it is not needed,
                                // and we can't wait any more on destroying
                                // the fragment.
                                View v = f.mAnimatingAway;
                                f.mAnimatingAway = null;
                                v.clearAnimation();
                            }
                        }
                        if (f.mAnimatingAway != null) {
                            // We are waiting for the fragment's view to finish
                            // animating away. Just make a note of the state
                            // the fragment now should move to once the animation
                            // is done.
                            f.mStateAfterAnimating = newState;
                            newState = Fragment.CREATED;
                        } else {
                            if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
                            if (!f.mRetaining) {
                                f.performDestroy();
                            }
                            f.mCalled = false;
                            f.onDetach();
                            if (!f.mCalled) {
                                throw new SuperNotCalledException("Fragment " + f
                                        + " did not call through to super.onDetach()");
                            }
                            if (!keepActive) {
                                if (!f.mRetaining) {
                                    makeInactive(f);
                                } else {
                                    f.mActivity = null;
                                    f.mFragmentManager = null;
                                }
                            }
                        }
                    }
            }
        }
       
        f.mState = newState;
    }


重要的终于到了啊!这个方法中会先依次走INITIALIZING,CREATED,ACTIVITY_CREATED代码段。之后会根据Activity的生命周期走自己相应的生命周期函数。在此对应的是STARTED,RESUMED;
由于是初次加载Fragment。所以f.mState是小于newState的。所以走的都是f.mState<newState中的switch语句。
首先看INITIALIZING状态:

case Fragment.INITIALIZING:
                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
                    if (f.mSavedFragmentState != null) {
                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
                                FragmentManagerImpl.VIEW_STATE_TAG);
                        f.mTarget = getFragment(f.mSavedFragmentState,
                                FragmentManagerImpl.TARGET_STATE_TAG);
                        if (f.mTarget != null) {
                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
                        }
                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
                        if (!f.mUserVisibleHint) {
                            f.mDeferStart = true;
                            if (newState > Fragment.STOPPED) {
                                newState = Fragment.STOPPED;
                            }
                        }
                    }
                    f.mActivity = mActivity;
                    f.mFragmentManager = mActivity.mFragments;
                    f.mCalled = false;
                    f.onAttach(mActivity);
                    if (!f.mCalled) {
                        throw new SuperNotCalledException("Fragment " + f
                                + " did not call through to super.onAttach()");
                    }
                    mActivity.onAttachFragment(f);
                    
                    if (!f.mRetaining) {
                        f.mCalled = false;
                        f.onCreate(f.mSavedFragmentState);
                        if (!f.mCalled) {
                            throw new SuperNotCalledException("Fragment " + f
                                    + " did not call through to super.onCreate()");
                        }
                    }
                    f.mRetaining = false;
                    if (f.mFromLayout) {
                        // For fragments that are part of the content view
                        // layout, we need to instantiate the view immediately
                        // and the inflater will take care of adding it.
                        f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
                                null, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mView.setSaveFromParentEnabled(false);
                            if (f.mHidden) f.mView.setVisibility(View.GONE);
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                        }
                    }
case Fragment.CREATED:


在f.mSavedFragmentState != null这个条件判断语句块中。是屏幕切换时或因其他原因引起的fragment被销毁后重新恢复时走的语句块。在此不用理会。接着后面,熟悉的代码出现了,f.onAttach(mActivity),第一个生命周期方法。这里面就可以拿到与此fragment相绑定的Activity的实例。接着往下看。f.onCreate(f.mSavedFragmentState)。走onCreate回调了。
而f.mFromLayout在此时为false。故不用理会。

接着。来看CREATED状态:
case Fragment.CREATED:
                    if (newState > Fragment.CREATED) {
                        if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                        if (!f.mFromLayout) {
                            ViewGroup container = null;
                            if (f.mContainerId != 0) {
                                container = (ViewGroup)mActivity.findViewById(f.mContainerId);
                                if (container == null && !f.mRestored) {
                                    throw new IllegalArgumentException("No view found for id 0x"
                                            + Integer.toHexString(f.mContainerId)
                                            + " for fragment " + f);
                                }
                            }
                            f.mContainer = container;
                            f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
                                    container, f.mSavedFragmentState);
                            if (f.mView != null) {
                                f.mView.setSaveFromParentEnabled(false);
                                if (container != null) {
                                    Animator anim = loadAnimator(f, transit, true,
                                            transitionStyle);
                                    if (anim != null) {
                                        anim.setTarget(f.mView);
                                        anim.start();
                                    }
                                    container.addView(f.mView);
                                }
                                if (f.mHidden) f.mView.setVisibility(View.GONE);
                                f.onViewCreated(f.mView, f.mSavedFragmentState);
                            }
                        }
                        
                        f.mCalled = false;
                        f.onActivityCreated(f.mSavedFragmentState);
                        if (!f.mCalled) {
                            throw new SuperNotCalledException("Fragment " + f
                                    + " did not call through to super.onActivityCreated()");
                        }
                        if (f.mView != null) {
                            f.restoreViewState();
                        }
                        f.mSavedFragmentState = null;
                    }
case Fragment.ACTIVITY_CREATED:


重点来了!newState此时的值为ACTIVITY_CREATED。故可以进入语句块,在内部先通过Activity的findViewById方法通过add的containerid来得到要添加fragment的ViewGroup。再将其赋给fragment的mContainer成员变量中。接下来通过fragment的onCreateView回调。将创建的view放入fragment的view成员变量中。接下来就是加载fragment的动画以及将创建的view通过addView方法放于容器中了。至此。成功将fragment嵌入到了界面上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: