My fragments in viewpager tab dont refresh

66,329

Solution 1

UPDATE: There is a better way, Please have a look here: Update ViewPager dynamically?


Removing content of this answer because it was a really bad way to access Fragments inside ViewPager, please see the above link for better approach.

Solution 2

The best way that I have discovered to simulate a "setOffscreenPageLimit(0)" behavior is by using an OnPageChangeListener in conjunction with overriding the getItemPosition method in your adapter. Something like this:

In your custom pager adapter:

@Override
public int getItemPosition(Object object) {
     return POSITION_NONE;
}

Then in your Activity containing the ViewPager:

final MyPagerAdapter adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
pager.setOnPageChangeListener(new OnPageChangeListener() {
     @Override
     public void onPageSelected(int position) {
          ... anything you may need to do to handle pager state ...
          adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
     }
}

This should have the same effect as setting the OffscreenPageLimit to 0. However, this functionality is sort of against what the ViewPager is designed to provide. If you are trying to implement a ViewPager in this way, it may be worth reevaluating your layout to be sure that a ViewPager is really what you want to use.

Solution 3

first override in the fragment method

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser){
        actionView();//call the method to be refreshed
    }
    else{
        //no
    }

}

Solution 4

It's because you can specify the number of fragment your viewpager will "keep in RAM" (setOffScreenPageLimit () :I think the default is 1). So your second fragment is not reloaded. And when you go to a tab 3 or 4, then your 2 firsts fragments are deleted, then recreated when you come back.

To refresh your fragment, there is many way to do it: you could implement a listener interface of your own in it to tell it when to refresh, or simply call a method that you would implement to update your contents.

Solution 5

In my experience, ViewPagers keep:

  • Your current tab
  • & 1 tab either side in memory

So when you switch between 1 and 2, nothing is happening under the hood - it's like they are simply being hidden / shown.

But when you navigate to tab 4, tabs 1 & 2 are destroyed (onDestroy() called), so when you navigate back to either of them, they are being re-created fresh (onCreate() called).

As psykhi suggests, you could setOffScreenPageLimit() to 0, so that each fragment is created every time you navigate to it.

If you were interested in keeping the other pages in memory for performance purposes, as they were designed with this is mind, you could use a messaging/event publishing system to send a message from tab 1 to tab 2 telling it to update when you submit the form on tab 1.

Share:
66,329
BlastFire
Author by

BlastFire

Updated on November 24, 2020

Comments

  • BlastFire
    BlastFire over 3 years

    i got viewpager with 4 tabs .. in each tab there is a fragment. my first tab is a fragment with a form (for example Users) after i click save, the data is inserted in the database. my second tab is another fragment with form but it uses data from the first tab (i am getting it from the database) to populate a spinner. now after i successfully inserted data from my first tab, in my second tab the spinner is empty. since my db query is implemented in onCreateView() in the second fragment, its called only once when the application is started, so changing between tab 1 i tab2 doesn't starts onCreateView() or even onResume(). The interesting thing for me is that if i go to tab4 and then return to tab2, my data is in my spinner properly, so somehow swiping two tabs away from my current tab refreshing my fragment. my question is how can i achieve proper refresh to my fragment when onCreateView() is called only once ?

    Edit i tried to put that method psykhi suggested like that:

        this.mViewPager.setOffscreenPageLimit(0);
        this.mViewPager.setAdapter(this.mPagerAdapter);
        this.mViewPager.setOnPageChangeListener(this);
    

    but it's not working for me. Am i missing something ?

  • BlastFire
    BlastFire over 11 years
    yep that will do the trick. i wonder about the setOffscreenPageLimit method though and why swiping two tabs away and then back to the original, only then my onCreateView is called again.
  • M-Wajeeh
    M-Wajeeh over 11 years
    Default value for setOffscreenPageLimit() is 1. That means 1 on each side of your current tab will be initialized/cached. When you go away 2 tabs then the tab in question is un-cached/destroyed. So coming back will initiate it again and everything will work fine this time.
  • silverFoxA
    silverFoxA about 9 years
    App crashes everytime i scroll through it and shows the error cast exception : package.fragment can not be casted to package.fragment$refreshlistener
  • kosiara - Bartosz Kosarzycki
    kosiara - Bartosz Kosarzycki over 8 years
    @Virus That's why page caching in ViewPager was introduced in the first place - to eliminate the lag
  • Harry Sharma
    Harry Sharma over 8 years
    Hello it gives java.lang.ClassCastException: what to do...urgent
  • M-Wajeeh
    M-Wajeeh over 8 years
    @Virus Use the mechanism mentioned here stackoverflow.com/questions/10849552/…
  • M-Wajeeh
    M-Wajeeh over 8 years
    @Hardeep see my comment above
  • DragonFire
    DragonFire over 5 years
    Its crazy it behaves like this.. for beginners one would think android studio is wierd
  • DragonFire
    DragonFire over 5 years
    i was thinking that copying and pasting fragment structure and modifying is causing this problem (because it does in xml files where you refactor id in one place it changes everywhere).. so i thought some wierd linkages could be there but this is totally different...