📜 ⬆️ ⬇️

Android ViewPager. How to replace one fragment with another

In this article I want to share the experience of using the ViewPager and FragmentStatePagerAdapter, which appeared in the compatibility package. More precisely, to tell what problems had to face and how they were solved. In particular, the replacement of one fragment to another.

Inspired by the post in the official blog android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html , began to try. The essence of the task was to include as fragments of the mail application as one of the page, other pages as the instant messenger application fragments.


There are several fragments of the mail application, but there is only one page for displaying them. For simplicity, consider two mail fragments - lists of folders and letters in the selected folder. The first user sees a fragment of the list of folders. When selecting a specific folder, the folder fragment is replaced with the corresponding fragment of letters in the same page.
')
But, like many (it’s worth searching the Internet for the query “android viewpager replace fragments”), I ran into a problem - one Fragment wasn’t replaced by another when using the ViewPager.

The solution was to transfer the ViewPager, PagerAdapter and FragmentStatePagerAdapter code from the source pack compatibility pack to your project and add the following function to the ViewPager:

public void notifyItemChanged(Object oldItem, Object newItem) { if (mItems != null) { for (ItemInfo itemInfo : mItems) { if (itemInfo.object.equals(oldItem)) { itemInfo.object = newItem; } } } invalidate(); } 


And in the FragmentStatePagerAdapter add:

 public void replaceFragmetns(ViewPager container, Fragment oldFragment, Fragment newFragment) { // ensure getItem returns newFragemtn after calling handleGetItemInbalidated() handleGetItemInbalidated(container, oldFragment, newFragment); startUpdate(container); // remove old fragment if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } int position = getFragmentPosition(oldFragment); while (mSavedState.size() <= position) { mSavedState.add(null); } mSavedState.set(position, null); mFragments.set(position, null); mCurTransaction.remove(oldFragment); // add new fragment while (mFragments.size() <= position) { mFragments.add(null); } mFragments.set(position, newFragment); mCurTransaction.add(container.getId(), newFragment); finishUpdate(container); container.notifyItemChanged(oldFragment, newFragment); } protected abstract void handleGetItemInbalidated(View container, Fragment oldFragment, Fragment newFragment); protected abstract int getFragmentPosition(Fragment fragment); 


The handleGetItemInbalidated () function is implemented in your class that inherits from the FragmentStatePagerAdapter. After calling it, the FragmentStatePagerAdapter .getItem () function should return newFragment. getFragmentPosition () is also implemented in the inherited class and returns the index of the fragment in the page list.

Now the replacement of fragments is done like this:
 mAdapter.replaceFragmetns(mViewPager, oldFragment, newFragment); 


I draw your attention to the fact that the FragmentStatePagerAdapter “unloads” (fragmentTransaction.remove ()) pages, which are further than one position from the current one. In my application page with a mail fragment should not be unloaded when scrolling.

To do this, override two functions in the FragmentStatePagerAdapter class:

 @Override public Object instantiateItem(View container, int position) { if (position == getCount() - 1) { if (mMailCahcedFragment == null) { return super.instantiateItem(container, position); } else { return mMailCahcedFragment; } } else { return super.instantiateItem(container, position); } } @Override public void destroyItem(View container, int position, Object object) { if (position == getCount() - 1) { } else { super.destroyItem(container, position, object); } } 


The condition (position == getCount () - 1) is due to the fact that the page with the post fragment is always the last.

Download the test project in Eclipse: files.mail.ru/I72IP7

Source: https://habr.com/ru/post/132406/


All Articles