I have ~20 fragments inside FragmentPagerAdapter that contains a list where it picks the fragments from so theres no recreation of fragments.
private List<TitledFragment> fragments;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
this.fragments = new ArrayList<TitledFragment>();
}
@Override
public Fragment getItem(int i) {
return fragments.get(i).getFragment();
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return fragments.get(position).getTitle();
}
public synchronized List<TitledFragment> getFragments() {
return fragments;
}
public synchronized void addFragment(TitledFragment fragment) {
fragments.add(fragment);
notifyDataSetChanged();
}
the FragmentPagerAdapter is set as adapter of ViewPager and after that I reorder the fragments(shuffling was just for test)
Collections.shuffle(mSectionsPagerAdapter.getFragments());
mSectionsPagerAdapter.notifyDataSetChanged();
and for some reason only order of titles is being changed, even if its returning different fragment for getItem as the order is different. Why is this and how can I get around it?
You also need to override getItemPosition()
. By default, this function always returns POSITION_UNCHANGED
, so that when you call notifyDataSetChanged()
, the adapter assumes that all of the fragments are still in the same position. (It does not call getItem()
again, since it thinks all of the necessary fragments are already created.) Your new getItemPosition()
should return the new position of each fragment after shuffling.
An easy hack is to always return POSITION_NONE
, and then the adapter will just discard all of the existing fragments, and recreate them in their correct positions when calling getItem()
. Of course, this is not efficient, and has the additional drawback that the current fragment being viewed may change. However, since there may possibly be some bugs in reordering the fragments - see my question here - the POSITION_NONE
approach may be the safest method.