Difference between FragmentPagerAdapter and FragmentStatePagerAdapter

Difference between FragmentPagerAdapter and FragmentStatePagerAdapter

FragmentPagerAdapter and FragmentStatePagerAdapter are both adapters used to adapt data to ViewPager in Android development. There are significant differences between the two in the way they use and manage Fragments.

When switching Fragments, FragmentPagerAdapter does not destroy the Fragment, but only calls the detach method in the transaction. Therefore, the view of the Fragment will be destroyed, but the instance of the Fragment will remain in the FragmentManager. The Fragments created in this way will never be destroyed, which is suitable for some static Fragments, such as a group of tabs. This may also cause the application to occupy too many resources when the number of Fragments is large.

When switching between different fragments, FragmentStatePagerAdapter will destroy the fragments that are no longer needed. Before destroying the fragment, the state information of the fragment (saved by the onSaveInstanceState(Bundle) method) will be saved in the Bundle. After switching back to the original page, the saved state can be used to restore and generate a new fragment. It is suitable for scenarios with a large number of pages or where fragments need to be loaded and destroyed dynamically, and can effectively manage memory usage.

FragmentPagerAdapter source code

 @Override public Object instantiateItem(ViewGroup container, int position) { if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } final long itemId = getItemId(position); // Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId); Fragment fragment = mFragmentManager.findFragmentByTag(name); if (fragment != null) { if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); mCurTransaction.attach(fragment); } else { fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } if (fragment != mCurrentPrimaryItem) { fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); } return fragment; }

In the instantiateItem method, the main thing is to add the Fragment to the FragmentManager. If it is not added to the FragmentManager, the add operation is performed, and if it is added to the FragmentManager, only the attach operation is performed.

 @Override public void destroyItem(ViewGroup container, int position, Object object) { if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v=" + ((Fragment)object).getView()); mCurTransaction.detach((Fragment)object); }

In the destroyItem method, only the detach operation is performed. The detach operation does not destroy the Fragment, and the Fragment is still managed by the FragmentManager.

FragmentStatePagerAdapter source code

 @Override public Object instantiateItem(ViewGroup container, int position) { if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return f; } } if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } Fragment fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment); if (mSavedState.size() > position) { Fragment.SavedState fss = mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (mFragments.size() <= position) { mFragments.add(null); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); @ mFragments.set(position, fragment); mCurTransaction.add(container.getId(), fragment); return fragment; }

FragmentStatePagerAdapter stores Fragments through an mFragments array and stores the state of Fragments when they are destroyed through the mSavedState array. The Fragment obtained through position may be empty (recycled). If it is empty, the getItem method will be called again to recreate a new Fragment, and then the state stored in mSavedState will be reassigned to the new Fragment to achieve the effect of Fragment recovery.

 @Override public void destroyItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object + " v=" + ((Fragment)object).getView()); while (mSavedState.size() <= position) { mSavedState.add(null); } mSavedState.set(position, fragment.isAdded() ? mFragmentManager.saveFragmentInstanceState(fragment) : null); mFragments.set(position, null); mCurTransaction.remove(fragment); }

When the item is not visible on the page, the state of the Fragment will be saved to mSavedState first, and the Fragment instance will be destroyed.

Summarize

FragmentPagerAdapter and FragmentStatePagerAdapter are both adapters used with ViewPager in Android development.

Similarities:

  • Inherited from PagerAdapter: Both inherit from PagerAdapter, with the same basic functions and usage.
  • Managing Fragments: These are adapters used to manage Fragments, enabling ViewPager to display a series of Fragments.
  • Maintain the current and previous and next fragment states: While displaying the current fragment, the Adapter will initialize the next fragment in advance and save the previous fragment of the current fragment in memory.

Differences:

(1) Fragment destruction strategy:

  • FragmentPagerAdapter: The created Fragment instance will not be destroyed, but saved in memory. When the Fragment is no longer visible, only the detach method is called to destroy the Fragment's view (View) and retain the Fragment instance. Switching back to the previous Fragment can quickly rebind the view without recreating the Fragment instance. This method is suitable for scenarios with a small number of Fragments that do not need to be created and destroyed frequently.
  • FragmentStatePagerAdapter: Completely destroy a fragment when it is no longer needed. When the fragment slides out of the screen, the instance and view will be destroyed. When switching back to the fragment, the fragment instance and view will be recreated. This method is suitable for scenes with a large number of fragments or when fragments need to be loaded and destroyed dynamically to avoid taking up too much memory.

(2) State preservation and restoration:

  • FragmentStatePagerAdapter: Before destroying the Fragment, the state information of the Fragment will be saved in the onSaveInstanceState(Bundle) method. When switching back to the original Fragment, you can use this saved state information to restore the state of the Fragment.
  • FragmentPagerAdapter: Since the Fragment instance will not be destroyed, there is no need to save the state before destruction, nor to reload the state when restoring.

The main difference between FragmentPagerAdapter and FragmentStatePagerAdapter is how they manage the Fragment lifecycle. The former retains the Fragment instance, which is suitable for scenarios with a small number of Fragments and do not need to be created and destroyed frequently; the latter destroys the Fragment when it is no longer needed, which is suitable for scenarios with a large number of Fragments or those that need to be loaded and destroyed dynamically.

<<:  Exploration and practice of Ctrip Hotel's unified cloud mobile phone platform

>>:  The key to optimizing Bitmap memory usage: image resolution, folder storage and loading strategy

Recommend

A brief discussion on internal scrolling layout

1. What is inner scrolling layout? The so-called ...

Muscovite: thin and hazy thousand-layer paper, mica screen with deep candlelight

This issue introduces a white mica specimen from ...

How to promote your App without spending a penny?

In the process of dividing up channel resources a...

Before I even took off my shoes, I could smell the stink of feet...

There is an embarrassment called foot odor. Espec...

Google's upcoming Android P features leaked

It is now March, and the official release of Andr...

Changsha Tea Tasting Peripheral Reliable Recommendation

Content: Changsha New Tea website appointment arr...

How much does it cost to receive happy birthday wishes from Russian beauties?

Yes, you read it right. A group of Russian girls ...

Component Library Design Guide: The Birth of a Component Library

Editor's Note: How to build a component libra...

ExoPlayer supports multiple media formats and streaming protocols

ExoPlayer Introduction ExoPlayer is an open sourc...