5

I am looking for an infinite loop to display pictures in a ViewPager2.

With a 'slide' page transformer (like default I think) between pictures, and also between last and first item, and first and last item.

The difficulty I found is:

  • to not have Integer.maxValue items,
  • having a real transition between first and last element and not a setCurrentItem(x, false) which is not great to see.

1 Answers1

7

I found a solution: having two fake items in the list (first and last element), and when we scroll from second to last we change to the n-2 item (-> last of real item). But the problem is a bad transition to see.

So I imagine a solution more reliable to my situation: duplicate the two lasts items and put them at the beginning of the array.

  • List before: [A, B, C, D, E, F]
  • List after transformation: [E', F', A, B, C, D, E, F]

The idea is first to display item A (position 2), when we scroll at item F (position n-1) we force to display item F' (position 1). When we scroll at item E' (position 0) we force to display item E (position n-2).

So, whenever the position, we always have an item on the left and an item on the right, and we always can scroll with a beautiful page transformer.

The limit is to have at least two items. But of course we do not have to scroll with only one item.

Java code:

public class MyPagerActivity extends Activity {
    private ViewPager2 pager;
    private final MyPagerAdapter adapter = new MyPagerAdapter();
    private ViewPager2.OnPageChangeCallback pageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(final int position) {
            super.onPageSelected(position);
            currentPosition = position;
            onFocusChange();
        }

        @Override
        public void onPageScrollStateChanged(final int state) {
            super.onPageScrollStateChanged(state);
            if (state == ViewPager2.SCROLL_STATE_IDLE) {
                if (currentPosition == 0) {
                    pager.setCurrentItem(fakeSize - 2, false);
                } else if (currentPosition == fakeSize - 1) {
                    pager.setCurrentItem(1, false);
                }
            } else if (state == ViewPager2.SCROLL_STATE_DRAGGING && currentPosition == fakeSize) {
                //we scroll too fast and miss the state SCROLL_STATE_IDLE for the previous item
                pager.setCurrentItem(2, false);
            }
        }
    };


    private ArrayList<String> itemList;
    private int fakeSize;
    private int realSize;
    private int currentPosition;

    @Override
    protected void onCreate(@Nullable final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.pager = findViewById(R.id.mypager_viewpager);
        this.pager.setAdapter(this.adapter);
        this.pager.registerOnPageChangeCallback(this.pageChangeCallback);
        this.pager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
        final ArrayList<String> itemList = null;//your data
        this.realSize = itemList.size();
        this.fakeSize = this.realSize + 2;
        this.itemList = transformListAndAddTwo(itemList);
        this.adapter.*updateList*(this.itemList);
        final int item = 2; //number two because we have two elements before the chosen one
        this.pager.setCurrentItem(item, false);
    }

    private void onFocusChange() {
        //Do something
    }

    /**
     * add two lasts item at beginning on the new array
     * @param itemList
     * @return
     */
    public static ArrayList<String> transformListAndAddTwo(final ArrayList<String> itemList) {
        final int size = itemList.size();
        final ArrayList<String> listTemp = new ArrayList<>(size + 2);
        for (int iPL = 0; iPL <= size + 2; iPL++) {
            listTemp.add(itemList.get((iPL + size - 2) % size));
        }
        return listTemp;
    }
}
  • trying to make this work without success. how is MyPagerAdapter class looks like? adapter.setPublicationList(); not resolved – esQmo_ Jun 28 '20 at 12:54
  • it is a method to update list items, not usefull here – Alexandre Gombert Jun 29 '20 at 11:49
  • 1
    I've been struggling with this case for weeks. I also needed the list to be editable and have some custom animations. This was the only way it all worked together. Thank you so much :) – Mohru Oct 11 '21 at 22:16