Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing ViewPager to enable infinite page scrolling

Jon Willis has posted on how to enable an infinite scrolling with his code.

In there he said that he made some changes in the ViewPager class in the android support library. Which changes have been made and how is it possible to "recompile" the library with the ViewPager change?

like image 787
thehayro Avatar asked Oct 14 '11 10:10

thehayro


People also ask

How do I stop ViewPager from scrolling?

A simple solution is to create your own subclass of ViewPager that has a private boolean flag, isPagingEnabled . Then override the onTouchEvent and onInterceptTouchEvent methods. If isPagingEnabled equals true invoke the super method, otherwise return .

Is ViewPager deprecated?

This function is deprecated. Set a drawable that will be used to fill the margin between pages. Set a drawable that will be used to fill the margin between pages. reverseDrawingOrder: Boolean, transformer: ViewPager.

What is difference between ViewPager and ViewPager2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .


2 Answers

I solved this problem very simply using a little hack in the adapter. Here is my code:

public class MyPagerAdapter extends FragmentStatePagerAdapter {     public static int LOOPS_COUNT = 1000;     private ArrayList<Product> mProducts;       public MyPagerAdapter(FragmentManager manager, ArrayList<Product> products)     {         super(manager);         mProducts = products;     }       @Override     public Fragment getItem(int position)     {         if (mProducts != null && mProducts.size() > 0)         {             position = position % mProducts.size(); // use modulo for infinite cycling             return MyFragment.newInstance(mProducts.get(position));         }         else         {             return MyFragment.newInstance(null);         }     }       @Override     public int getCount()     {         if (mProducts != null && mProducts.size() > 0)         {             return mProducts.size()*LOOPS_COUNT; // simulate infinite by big number of products         }         else         {             return 1;         }     } }  

And then, in the ViewPager, we set current page to the middle:

mAdapter = new MyPagerAdapter(getSupportFragmentManager(), mProducts); mViewPager.setAdapter(mAdapter); mViewPager.setCurrentItem(mViewPager.getChildCount() * MyPagerAdapter.LOOPS_COUNT / 2, false); // set current item in the adapter to middle 
like image 102
petrnohejl Avatar answered Oct 19 '22 23:10

petrnohejl


Thank you for your answer Shereef.

I solved it a little bit differently.

I changed the code of the ViewPager class of the android support library. The method setCurrentItem(int)

changes the page with animation. This method calls an internal method that requires the index and a flag enabling smooth scrolling. This flag is boolean smoothScroll. Extending this method with a second parameter boolean smoothScroll solved it for me. Calling this method setCurrentItem(int index, boolean smoothScroll) allowed me to make it scroll indefinitely.

Here is a full example:

Please consider that only the center page is shown. Moreover did I store the pages seperately, allowing me to handle them with more ease.

private class Page {   View page;   List<..> data; } // page for predecessor, current, and successor Page[] pages = new Page[3];     mDayPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {          @Override         public void onPageSelected(int position) {         }          @Override         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}          @Override         public void onPageScrollStateChanged(int state) {              if (state == ViewPager.SCROLL_STATE_IDLE) {                  if (mFocusedPage == 0) {                     // move some stuff from the                                              // center to the right here                     moveStuff(pages[1], pages[2]);                      // move stuff from the left to the center                      moveStuff(pages[0], pages[1]);                     // retrieve new stuff and insert it to the left page                     insertStuff(pages[0]);                 }                 else if (mFocusedPage == 2) {                       // move stuff from the center to the left page                     moveStuff(pages[1], pages[0]);                      // move stuff from the right to the center page                     moveStuff(pages[2], pages[1]);                      // retrieve stuff and insert it to the right page                                             insertStuff(pages[2]);                 }                  // go back to the center allowing to scroll indefinitely                 mDayPager.setCurrentItem(1, false);             }         }     }); 

However, without Jon Willis Code I wouldn't have solved it myself.

EDIT: here is a blogpost about this:

like image 25
thehayro Avatar answered Oct 20 '22 01:10

thehayro