Home » Android » ViewPager.setOffscreenPageLimit(0) doesn't work as expected

ViewPager.setOffscreenPageLimit(0) doesn't work as expected

Posted by: admin November 29, 2017 Leave a comment

Questions:

The fragments I use in my ViewPager instance are quite resource intensive, so I’d only like to load one at a time. When I try the following:

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

My FragmentStatePagerAdapter.getItem(int position) override function is called 3 times, which is what happens when I call mViewPager.setOffscreenPageLimit(1). I would expect it to only be called once, because I specified 0 offscreen pages.

I believe I’m calling everything correctly, because if I call mViewPager.setOffscreenPageLimit(2), FragmentStatePagerAdapter.getItem(int position) is called 5 times as I would expect.

Does ViewPager require a minimum of 1 offscreen pages, or am I doing something wrong here?

Answers:

Does ViewPager require a minimum of 1 offscreen pages

Yes. If I am reading the source code correctly, you should be getting a warning about this in LogCat, something like:

Requested offscreen page limit 0 too small; defaulting to 1

Questions:
Answers:

The best way that I found was setUserVisibleHint
add this to your fragment

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // load data here
    }else{
       // fragment is no longer visible
    }
}

Questions:
Answers:

First Add

   boolean _areLecturesLoaded = false;

than

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && !_areLecturesLoaded) {
        //Load Your Data Here like.... new GetContacts().execute();

        _areLecturesLoaded = true;
    }
else{
     }
}

Questions:
Answers:

You can try like this :

public abstract class LazyFragment extends Fragment {
    protected boolean isVisible;
    /**
     * 在这里实现Fragment数据的缓加载.
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }
    protected void onVisible(){
        lazyLoad();
    }
    protected abstract void lazyLoad();
    protected void onInvisible(){}
protected abstract void lazyLoad();
protected void onInvisible(){}

Questions:
Answers:

ViewPager is default to load the next page(Fragment) which you can’t change by setOffscreenPageLimit(0). But you can do something to hack.
You can implement onPageSelected function in Activity containing the ViewPager. In the next Fragment(which you don’t want to load), you write a function let’s say showViewContent() where you put in all resource consuming init code and do nothing before onResume() method. Then call showViewContent() function inside onPageSelected. Hope this will help.

Questions:
Answers:

for the “instantiateItem” function, just prepare the fragment, but don’t load the heavy content.

Use “onPageChangeListener” , so that each time you go to a specific page, you load its heavy content and show it.

Questions:
Answers:

this may be old thread but this seems to work for me. Override this function :

@Override
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible);

    if ( menuVisible ) {
        /**
         * Load your stuffs here.
         */
    } else  { 
        /**
         * Fragment not currently Visible.
         */
    } 
}

happy codings…

Questions:
Answers:

I kind of have the same problem. I found some useful code on this site and transform it.

The min int for mViewPager.setOffscreenPageLimit(…); is 1, so even if you change it to 0 you will still have 2 pages loaded.

First thing to do is to create a static int we will call maxPageCount and override FragmentStatePagerAdapter method getCount() to return maxPageCount:

    @Override
    public int getCount() {
        return maxPageCount;
    }

Create then a static method accessible from any where in the program that will allow you to change this maxCount:

public static void addPage(){
    maxPageCount++; //or maxPageCount = fragmentPosition+2
    mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here.
}

Now initialize maxPageCount to 1. When ever you want you can add another page.
In my case when I needed the user to treat the current page first before generated the other. He do it and then, without problem can swipe to the next page.

Hope it help someone.