4

I am displaying a ViewPager containing only ImageViews. But, I need it to happen continuously in a circular manner. For Ex : ...c > B > A > B > c...

Manjunath
  • 2,063
  • 2
  • 29
  • 60

3 Answers3

4

Just implement the ViePager.OnPageChangeListener:

YOUR_VIEWPAGER.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
      currentPage = position;
    }
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
      // not needed
    }
    @Override
    public void onPageScrollStateChanged(int state) {
      if (state == ViewPager.SCROLL_STATE_IDLE) {
        int pageCount = pages.size();

        if (currentPage == 0){
          YOUR_VIEWPAGER.setCurrentItem(pageCount-2,false);
        } else if (currentPage == pageCount-1){
          YOUR_VIEWPAGER.setCurrentItem(1,false);
        }
      }
    }
  });
Andreas
  • 1,617
  • 15
  • 18
  • 1
    This works fine, but it doesn't show scrolling effect when it switches from 0th item to last item AND from last item to 0th item. – Manjunath Nov 07 '12 at 06:13
  • you have to change the if-statement in onPageScrollStateChanged() to match the view offset, e.g. YOUR_VIEWPAGER.setCurrentItem(pageCount-2,false); must match your view;) – Andreas Nov 07 '12 at 06:17
  • 1
    Yup, its fine but, I am concerned about the animation to be shown while switching between views(0th & last item). I think there is no solution for this :) – Manjunath Nov 07 '12 at 06:41
  • Zeroth Location Item is Missing at second time onwards – Chaitu Jul 10 '13 at 11:49
2

try this one. it will get results like C <--> A <--> B <--> C <--> A

viewPager?.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
      var currentPage : Int = 0
      var mPreviousPosition : Int = 0
      var mIsEndOfCycle = false
      override fun onPageScrollStateChanged(state: Int) {
        val pageCount = viewPager?.adapter?.count
        if (state == ViewPager.SCROLL_STATE_IDLE) {
          if (mPreviousPosition == currentPage && !mIsEndOfCycle) {
            if (currentPage == 0) {
              pageCount?.minus(1)?.let { viewPager?.setCurrentItem(it, false) };
            } else {
              viewPager?.setCurrentItem(0, false);
            }
            mIsEndOfCycle = true;
          } else {
            mIsEndOfCycle = false;
          }
          mPreviousPosition = currentPage;
        }
      }

      override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

      override fun onPageSelected(position: Int) {
        currentPage = position
      }

    })
Muhammed Haris
  • 340
  • 1
  • 5
  • 15
1

The following did it for me. I didn't want the user to scroll "back" from the first page to the last. So basically I have three different screens, but I actually have four in the adapter, like so: A -> B -> C -> A. When the user hits the second 'A' page, and the pager state becomes IDLE, I seamlessly switch to the first 'A' page. I even have a page indicator which I've similarly overridden.

val pageChangeCallback = object : ViewPager2.OnPageChangeCallback() {
        override fun onPageScrollStateChanged(state: Int) {
            super.onPageScrollStateChanged(state)

            if (state == ViewPager.SCROLL_STATE_IDLE) {
                if (viewPager.currentItem == NUM_PAGES - 1) {
                    viewPager.setCurrentItem(0, false)
                }
            }
        }
    }
Dharman
  • 30,962
  • 25
  • 85
  • 135
Miguel Lasa
  • 470
  • 1
  • 7
  • 19