# # # 1. The overview


In my last blog post, I talked briefly about the use of fragments and wrote a basic example. Now I will integrate them into the project. Attached to the video address: http://pan.baidu.com/s/1mhUus56

# # # 2. Effect of implementation


2.1 Integration of the previous example:

The list and the scroll bar are simply accessing the interface to get the data, which is covered in Android Studio custom templates and Android Unlimited AD rotation. One of the oddities we found when we went straight into it was that it was not normal to reload data after switching. So the general idea is that we’re going to implement it in a different way, of course you can do it in other ways like ViewPager+Fragment but we need to preload it otherwise we’re going to have a problem, and once we preload it we’re going to have to access the network, Even though the user may exit the App without switching the Fragment, all the Fragment data is actually loaded, and the homepage may crash or cause memory overflow once it is complicated. My signature is, forget not remember, insist not to give up, but as long as alive… 2.2 Fragment source code:

Add (@idres int containerViewId, Fragment Fragment) and commit() to add a Fragment to a ViewGroup

@Override
    protected void initData() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mHomeFragment = new HomeFragment();
        fragmentTransaction.add(R.id.main_tab_fl, mHomeFragment);
        fragmentTransaction.commit();
    }
Copy the code

We click on the Add method and see that it is abstract:

    /**
     * Calls {@link #add(int, Fragment, String)} with a null tag.
     */
    public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment);
Copy the code

Click fragmentManager. BeginTransaction () found that is also an abstract method:

	/**
     * Start a series of edit operations on the Fragments associated with
     * this FragmentManager.
     * 
     * <p>Note: A fragment transaction can only be created/committed prior
     * to an activity saving its state.  If you try to commit a transaction
     * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()}
     * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart}
     * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error.
     * This is because the framework takes care of saving your current fragments
     * in the state, and if changes are made after the state is saved then they
     * will be lost.</p>
     */
    public abstract FragmentTransaction beginTransaction();
Copy the code

So only click getSupportFragmentManager () method of this method in FragmentActivity:

	/**
     * Return the FragmentManager for interacting with fragments associated
     * with this activity.
     */
    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }
Copy the code

All the way to find the add method, found that there is no comment, the Google engineer is a bit of a slow pace! I’ll just have to do it myself and write where I need to. The add method simply sets the required parameters and doesn’t do anything, which is why Google is so adamant that we don’t forget to commit() :

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

	private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) { fragment.mFragmentManager = mManager; // A tag is a unique identifier that can be used to find the Fragment from the FragmentManagerif(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); } // Specify the Fragment ContainerId and FragmentId as the ids of the ViewGroup in the layout we passed in. fragment.mContainerId = fragment.mFragmentId = containerViewId; } // what is Op? Op Op = new Op(); op.cmd = opcmd; op.fragment = fragment; addOp(op); } 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++;
    }
Copy the code

Since the add method just sets a few parameters, something must have been done in commit() to find and find a method (I’ll skip some of the code) :

void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive){ // ... F.attach (mhost. getContext()); // When called, the Fragment's onAttach(Activity Activity) lifecycle method is executedif (f.mParentFragment == null) {
                    mHost.onAttachFragment(f);
                }

                if(! f.mRetaining) { f.performCreate(f.mSavedFragmentState); // Execute the lifecycle onCreate(savedInstanceState); } f.mRetaining =false;
                if (f.mFromLayout) {
	                ViewGroup container = null;
                    if(f.mContainerId ! = 0) {/ / found in the activity we need to store the fragments ViewGroup layout container = (ViewGroup) mContainer. OnFindViewById (f. may ContainerId);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)); } } // 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); // This method then executes the onCreateView() lifecycle and f.view is the View returned by our own override Fragmentif(f.mView ! = null) { f.mInnerView = f.mView; // the v4 package is compatible with versions up to 11if (Build.VERSION.SDK_INT >= 11) {
                            ViewCompat.setSaveFromParentEnabled(f.mView, false);
                        } else {
                            f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                        }
						
						if(container ! = null) { Animation anim = loadAnimation(f, transit,true,
                            transitionStyle);
                            if(anim ! = null) {setHWLayerAnimListenerIfAlpha(f.mView, anim); f.mView.startAnimation(anim); } // If the ViewGroup is not null, add the View obtained from the onCreateView() lifecycle to the layout. Fragment can be thought of as a custom class // acquired by onCreateView() to add to a ViewGroup of a FragmentActivity // except that it has its own life cycle...... container.addView(f.mView); } // If it is hidden then set it to invisibleif(f.mHidden) f.mView.setVisibility(View.GONE); // Execute onViewCreated() lifecycle method f.onViewCreated(F.view, f.saved FragmentState); }else {
                        f.mInnerView = null;
                    }
		
					f.performActivityCreated(f.mSavedFragmentState);
                    if(f.mView ! = null) { f.restoreViewState(f.mSavedFragmentState); } f.mSavedFragmentState = null; } // code omitted...... }} // since we wrote the add method in the Activity's onCreate() method, we did some processing......Copy the code

Now that you know how the Fragment works, let’s look at what happens in the replace method. It’s almost the same as add, except that int opcmd becomes OP_REPLACE:

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

Copy the code

Mmanager.removefragment (old, transition, transitionStyle) is called to remove the original Fragment and add the current Fragment to it. Where was Huadong before that and everything he did and wrote was killed and rebuilt.

if(mManager.mAdded ! = null) {for (int i = mManager.mAdded.size() - 1; i >= 0; i--) {
		Fragment old = mManager.mAdded.get(i);
        if (old.mContainerId == containerId) {
             if (old == f) {
                 op.fragment = f = null;
             } else {
                if (op.removed == null) {
                    op.removed = new ArrayList<Fragment>();
                }
                op.removed.add(old);
                old.mNextAnim = exitAnim;
				if(mAddToBackStack) { old.mBackStackNesting += 1; } mManager.removeFragment(old, transition, transitionStyle); }}}}if(f ! = null) { f.mNextAnim = enterAnim; mManager.addFragment(f,false);
}
Copy the code

	private void homeRbClick() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        List<Fragment> fragments = fragmentManager.getFragments();
        for (Fragment fragment : fragments) {
            fragmentTransaction.hide(fragment);
        }

        fragmentTransaction.show(mHomeFragment);
        fragmentTransaction.commit();
    }

    @OnClick(R.id.find_rb)
    private void findRbClick() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        List<Fragment> fragments = fragmentManager.getFragments();
        for (Fragment fragment : fragments) {
            fragmentTransaction.hide(fragment);
        }

        if(mFindFragment == null){
            mFindFragment = new FindFragment();
            fragmentTransaction.add(R.id.main_tab_fl,mFindFragment);
        }else {
            fragmentTransaction.show(mFindFragment);
        }

        fragmentTransaction.commit();
    }

    @OnClick(R.id.new_rb)
    private void newRbClick() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        List<Fragment> fragments = fragmentManager.getFragments();
        for (Fragment fragment : fragments) {
            fragmentTransaction.hide(fragment);
        }

        if(mNewFragment == null){
            mNewFragment = new NewFragment();
            fragmentTransaction.add(R.id.main_tab_fl,mNewFragment);
        }else {
            fragmentTransaction.show(mNewFragment);
        }

        fragmentTransaction.commit();
    }

    @OnClick(R.id.message_rb)
    private void messageRbClick() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        List<Fragment> fragments = fragmentManager.getFragments();
        for (Fragment fragment : fragments) {
            fragmentTransaction.hide(fragment);
        }

        if(mMessageFragment == null){
            mMessageFragment = new MessageFragment();
            fragmentTransaction.add(R.id.main_tab_fl,mMessageFragment);
        }else {
            fragmentTransaction.show(mMessageFragment);
        }

        fragmentTransaction.commit();
    }
Copy the code

Here have had too much to write in the video is made a code optimization, specific attached video address: http://pan.baidu.com/s/1mhUus56