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

前端 未结 11 817
抹茶落季
抹茶落季 2020-11-22 13:02

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:

mV         


        
相关标签:
11条回答
  • 2020-11-22 13:54

    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
    
    0 讨论(0)
  • 2020-11-22 13:57

    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.

    0 讨论(0)
  • 2020-11-22 14:00

    First Add

       boolean isFragmentLoaded = false;
    

    than

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && !isFragmentLoaded) {
            //Load Your Data Here like.... new GetContacts().execute();
    
            isFragmentLoaded = true;
        }
    else{
         }
    }
    
    0 讨论(0)
  • 2020-11-22 14:00

    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.

    0 讨论(0)
  • 2020-11-22 14:03

    in my case i wanted to start some animations in views, but with setUserVisibleHint got some issues ...
    my solution is :

    1/ addOnPageChangeListener for your adapter :

    mViewPager.addOnPageChangeListener(this);
    

    2/ implement OnPageChangeListener :

    public class PagesFragment extends Fragment implements ViewPager.OnPageChangeListener
    

    3/ override the 3 methodes :

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
    {
    
    }
    
    @Override
    public void onPageSelected(int position)
    { 
    }
    
    @Override
    public void onPageScrollStateChanged(int state)
    {
    }
    

    4/ declare and initialize this variable on your class

    private static int mTabState = 1;
    

    notice : i have three fragments in my adapter, and use mTabState for setCurrentItem and current position of adapter which recognize which fragment is show to user in time ... 5/ in onPageSelected method add this codes :

    if (mTabState == 0 || position == 0)
        {
            Intent intent = new Intent("animation");
            intent.putExtra("current_position", position);
            LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
        }
    

    if previous page or current page is page 0(fragment in position 0) then do this stuff

    6/ now in your fragment class (fragment in position 0 of adapter), you must create broadcast receiver and register it in onResume method and unregister it onPause methos :

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            if (Objects.equals(intent.getAction(), "animation"))
            {
                int currentPosition = intent.getIntExtra("current_position", 0);
                if (currentPosition == 0)
                {
                    startAnimation();
                    setViewsVisible();
                } else
                {
                    setViewsInvisible();
                }
            }
        }
    };
    
    @Override
    public void onResume()
    {
        super.onResume();
        LocalBroadcastManager.getInstance(mContext).registerReceiver(broadcastReceiver, new IntentFilter("animation"));
    }
    
    @Override
    public void onPause()
    {
        super.onPause();
        LocalBroadcastManager.getInstance(mContext).unregisterReceiver(broadcastReceiver);
    }
    

    summary : i have Fragment Pager Adapter witch shows Three Fragments in it, I want show some Animations on Views in Fragment in Position 0 of Adapter, For this I use BroadcastReceiver. When Fragment is Picked I start the Animation method and shows the Views to User, When Fragment is not Showing to User I try to Invisible Views...

    0 讨论(0)
提交回复
热议问题