[Android] Fragment source code analysis (2) Status

Source: Internet
Author: User

[Android] Fragment source code analysis (2) Status

As mentioned above, the question is how to construct the View parameter in Fragment when the onCreateView of the Activity is called. To answer this question, we must first understand the Fragment status, which is a very important part of Fragment management. Let's take a look at some core callbacks provided by FragmentActivity:

@Override    protected void onCreate(Bundle savedInstanceState) {        mFragments.attachActivity(this, mContainer, null);        // Old versions of the platform didn't do this!        if (getLayoutInflater().getFactory() == null) {            getLayoutInflater().setFactory(this);        }        super.onCreate(savedInstanceState);....        mFragments.dispatchCreate();    }
Let's follow the mFragments. dispatchCreate method:

public void dispatchCreate() {        mStateSaved = false;        moveToState(Fragment.CREATED, false);    }

We can see that for FragmentManager, a state conversion is performed. As mentioned in the previous article, FragmentManager is an important class that undertakes the core work of Fragment management. It has its own state machine, and its state can be understood as basically synchronizing with the Activity itself.

Maintain a state in the Fm. When you import a Fragment, the purpose of the Fm is to make the Fragment and its state basically consistent.

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

We can see that every change in the FragmentManager status will cause a change in the Fragment status in the mActive. MActive is all Fragment containers managed by FragmentManager. Let's take a look at several states of Fragment:

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.

It can be seen that, in fact, the closer your status is to the back, the larger your status value is. In fact, this is also cleverly used in Fm management.

 if (f.mState < newState) {  ...} else {  ...}

For f. mState

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

F. mFromLayout indicates whether your Fragment is generated from the layout. xml file. The View is generated by calling javasmcreateview.

View performCreateView(LayoutInflater inflater, ViewGroup container,            Bundle savedInstanceState) {        if (mChildFragmentManager != null) {            mChildFragmentManager.noteStateNotSaved();        }        return onCreateView(inflater, container, savedInstanceState);    }

Yes, here is the source of the onCreateView callback that we are very familiar. Of course, we still belong to the Fragment. INITIALIZING status. However, when Fragment is called, FragmentManageer enters the Create state. That is to say, the newState parameter should be created. So let's proceed with the code:

 case Fragment.CREATED:                if (newState > Fragment.CREATED) {                    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;                }
We can see that this code is used to import FragmentManager in the "Create" or "or" Fragment "status instead of" layout. xml "mode. Why? Because after onCreate, basically your control is generated almost when it is in the Create State. All you need to do is to find the container corresponding to Fragment in the generated control, then load your control. At the same time, we also see the Fragment animation processing:

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;                        }
The processing of such animations and parameter configuration will be discussed later in the Fragment transaction.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.