Reputation: 10708
I am not able to reuse fragment in FragmentPagerAdapter.. Using destroyItem() method, It is deleting the fragment but still does not called getItem() again..There are just 2-3 Images so I am using FragmentPagerAdapter Instead of FragmentStatePagerAdapter..
public class ExamplePagerAdapter extends FragmentPagerAdapter {
ArrayList < String > urls;
int size = 0;
public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
super(fm);
urls = res;
size = urls.size();
}
@Override
public int getCount() {
if (urls == null) {
return 0;
} else {
return size;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new FloorPlanFragment();
Bundle b = new Bundle();
b.putInt("p", position);
b.putString("image", urls.get(position));
Log.i("image", "" + urls.get(position));
fragment.setArguments(b);
return fragment;
}
}
And In FragmentActivity,
pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2));
Upvotes: 129
Views: 39931
Reputation: 4586
Using a FragmentStatePagerAdapter
didn't fully fix my problem which was a similar issue where onCreateView
was not being called for child fragments in the view pager. I am actually nesting my FragmentPagerAdapter
inside of another Fragment
therefore the FragmentManager
was shared throughout all of them and thus retaining instances of the old fragments. The fix was to instead feed an instance of the getChildFragmentManager
to the constructor of the FragmentPagerAdapter
in my host fragment. Something like...
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());
The getChildFragmentManager()
method is accessible via a fragment and this worked for me because it returns a private FragmentManager
for that fragment specifically for situations in which nesting fragments is needed.
getChildFragmentManager()
your minimum API version must be atleast 17 (4.2)
, so this may throw a wrench in your gears. Of course, if you are using fragments from the support library v4 you should be okay.Upvotes: 173
Reputation: 2704
method getItem()
is used only to create new items. Once they created, this method will not be called. If you need to get item that is currently in use by adapter, use this method:
pagerAdapter.instantiateItem(viewPager, TAB_POS)
Upvotes: 4
Reputation: 18819
Override long getItemId (int position)
FragmentPagerAdapter
caches the fragments it creates using getItem
. I was facing the same issue- even after calling notifyDataSetChanged()
getItem
was not being called.
This is actually a feature and not a bug. You need to override getItemId
so that you can correctly reuse your fragments. Since you are removing fragments, your positions are changing. As mentioned in the docs:
long getItemId (int position)
Return a unique identifier for the item at the given position.
The default implementation returns the given position. Subclasses should override this method if the positions of items can change.
Just provide a unique id to each fragment and you're done.
Using a FragementStatePagerAdapter
or returning POSITION_NONE
in int getItemPosition (Object object)
is wrong. You will not get any caching.
Upvotes: 10
Reputation: 10708
KISS Answer:
Simple use FragmentStatePagerAdapter instead of FragmentPagerAdapter.
I got the answer.. Firstly I thought to delete this question as I am doing a very silly mistake but this answer will help someone who is facing the same problem that Instead of FragmentPagerAdapter
, use FragmentStatePagerAdapter
.
As @BlackHatSamurai mentioned in the comment:
The reason this works is because
FragmentStatePagerAdapter
destroys as Fragments that aren't being used.FragmentPagerAdapter
does not.
Upvotes: 317
Reputation: 22212
I did what @kanika and @Jraco11 had posted but I still had the problem.
So, after a lot of changes, I found one that worked for me and was added to my FragmentPagerAdapter the next code:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
According to what I read, getItemPosition is used to notify the ViewPager whether or not to refresh an item, and to avoid updates if the items at the visible positions haven't changed.
Upvotes: 5
Reputation: 7405
I found that setting a listener on the tab-layout stopped this from being called, probably because they only have space for one listener on tabLayout.setOnTabSelectedListener
instead of an array of listeners.
Upvotes: 0
Reputation: 4956
There are two different scenarios : 1.) You have same layout for every pager : In that case, it will be better if you'll extend your custom adapter by PagerAdapter and return a single layout.
2.) You have different layout for every pager : In that case, it will be better if you'll extend your custom adapter by FragmentStatePagerAdapter and return different fragmets for every pager.
Upvotes: 2