1

When viewpager displays one fragment, it will automatically load the fragment pages around it for performance reasons. In my fragments, i have recycleviews with a popup menu to delete one item in the list.

I am facing a problem of deleting one item from one fragment, but that item still exists in the other preloaded fragments after I scroll to them. It works only if I force the viewpager to reload the contents of its fragments by manually scrolling back and forth the fragments.

Is there a way to force reload the preloaded fragments by viewpager?

usernotnull
  • 3,480
  • 4
  • 25
  • 40

5 Answers5

1

Your problem can be solved by using Interface. Google suggest using callbacks\listeners that are managed by your main Activity for communicating between fragments.You can use Interface which tells the other fragment to refresh its listview when you delete an item in current fragment.

For an overview http://developer.android.com/training/basics/fragments/communicating.html

Also a good question about this How to pass data between fragments

Community
  • 1
  • 1
Jithin Sunny
  • 3,352
  • 4
  • 26
  • 42
  • I am using Callbacks to communicate between fragments/activity already. However I see how it may solve the problem. My next question, to try it out, is how do I reference **preloaded** fragments by the viewpager to be able to communicate with them? – usernotnull Dec 07 '15 at 09:31
  • 1
    please look into this page http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager – Jithin Sunny Dec 07 '15 at 09:34
1

First create an interface to detect changes in your RecyclerView:

public interface MyRecyclerViewChangeListener(){
   void onRecyclerViewDataChanged(int id);
}

Create a static variable in your Fragment or Activity which contains your viewpager:

public static List<MyRecyclerViewChangeListener> mListeners = new ArrayList();

Implement your interface to your ViewPagerFragments and do what you want in method you implemented.

In your fragment's onResume register your listener to mListeners like blow to detect changes:

MyFragmentOrActivity.mListeners.add(this);

And in your fragment's onPause unregister your listener:

MyFragmentOrActivity.mListeners.remove(this);

Finally notify your listeners when your recyclerview data changed:

for(MyRecyclerViewChangeListener listener : mListeners){
    listener.onRecyclerViewDataChanged(id);
}

Edit : If you are changing your recyclerview's data after an async task result such as a web api call, you can register your listener in fragment's onCreateView method and un register in onDestroyView method. So you can catch changes in your fragments.

savepopulation
  • 11,736
  • 4
  • 55
  • 80
0

Try setting mViewPager.setOffscreenPageLimit(1) such that it will not pre-cache any fragment or you could use FragmentStatePagerAdapter inside viewPager to achieve what you want.

Edit 1: So Conclusion is : 1) Use local broadcast mechanism to update the fragments present in ViewPager adapter

2) Use handler mechanism to refresh these fragments

3) if you want to blindly update these fragments once they are visible to users then do it inside onPageChangeListener of view pager method.

dex
  • 5,182
  • 1
  • 23
  • 41
  • Didn't work, I initially thought about the same thing. Unfortunately the mViewPager.setOffscreenPageLimit(1) means it will preload 1 page before/after the current one showing. Same thing goes for FragmentStatePagerAdapter, according to docs, "When pages are not visible to the user, their entire fragment **MAY** be destroyed" Which means it may ass well _not_ be destroyed, especially if the action just happened and the user immediately scrolled to the next fragment – usernotnull Dec 07 '15 at 09:18
  • @RJFares : you want your fragment should be refreshed as soon as it is visible to users ? – dex Dec 07 '15 at 09:49
  • I want the fragments that are preloaded (around the currently visible fragment) to refresh after i call a deleteItem() on the visible one – usernotnull Dec 07 '15 at 09:52
  • 1
    RJFares : as suggested by @Sunny you have followings options : 1) send Local broadcast to other fragments and accordingly they will update them. 2) have some handler which take care of refreshing these fragments.3) update fragment blindly as soon as it is visible to users no matter whether refreshing these fragments required or not. – dex Dec 07 '15 at 10:05
0

I am not sure if i'm getting your question right but i think this should do it.

YourViewpager.setOffscreenPageLimit(0);

Now the fragment should be destroyed if it is not active and will be recreated if you open it again.So the data change should be recognized.

Hope I could help

Dolan
  • 103
  • 1
  • 1
  • 9
  • Doesn't work .setOffScreenPageLimit(0) is same as (1), because it can't be less than 1, and 1 means it preloads 1 page before/after the currently showing one – usernotnull Dec 07 '15 at 09:17
  • Did you try using the "addOnPageChangeListener" ? – Dolan Dec 07 '15 at 09:23
0

The answers helped me find the solution.

For future reference, I used a callback every time I used deleteItem(), and took a list of the loaded frags by using the method [FragmentHostingViewPager].getChildFragmentManager().getFragments()

Then I iterated through each fragment as long as each fragment was not null, and called a refresh() method on them.

Rami
  • 7,879
  • 12
  • 36
  • 66
usernotnull
  • 3,480
  • 4
  • 25
  • 40