1

I'm working on a Circular ViewPager, and i've implemented this exactly solution (https://stackoverflow.com/a/12965787/1083564).

The only thing is missing, is the fact that i need to smoothScroll when i'm using the setCurrentItem(int i, bol b) method, that instantly goes to the pixel limit, without using the smoothScroll.

I already have the access to use this method, using the following code:

package android.support.v4.view;

import android.content.Context;
import android.util.AttributeSet;

public class MyViewPager extends ViewPager {

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attr) {
        super(context, attr);
    }

    public void smoothScrollTo(int x, int y, int velocity) {
        super.smoothScrollTo(x, y, velocity);
    }

}

But i couldn't figure it out where and how to use it. I have the number of pixels that i need to run smoothly by using this code inside the setOnPageChangeListener on my ViewPager:

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    Log.d( "viewpager", positionOffsetPixels+"");
}

Before it goes to 0, instantly, because of the setCurrentItem, i have the value of pixels left to reach 0 (to the left) or x (to the right, depending of screen). I dont know how can i get this x number too.

PS: I think this solution is the exatcly one used by IMDB app. You can see this scrolling from the first to the last but one, without remove your finger (use 2 fingers to do it). You will see that the "white limit" will show from the left side of the ViewPager. The only difference is that they know how to smooth scroll after using the setCurrentItem.

If you need some more information, please, ask! Thanks!

Community
  • 1
  • 1
Otuyh
  • 2,014
  • 5
  • 21
  • 37

2 Answers2

3

Issue: When you detect circular scrolling has to be perfomed, calling setCurrentItem immediately will cause the ViewPager to scroll to the real fragment immediately without smooth scrolling as it is set to false.

Solution: Instead allow the ViewPager to scroll to the fake fragment smoothly as it does for other fragments and then scroll to the real fragment after some delay with smooth scrolling set to false. User will not notice the change.

When we are performing circular scrolling, call setCurrentItem in a runnable with some delay. Use onPageSelected to know the index of the page selected.

public void onPageSelected(int position) {

    // Consider eg. : C' A B C A'

    boolean circularScroll = false;
    if(position == 0) {
        // Position 0 is C', we need to scroll to real C which is at index 3. 
        position = mPager.getAdapter().getCount() - 2;
        circularScroll = true;
    }

    int lastIndex = mPager.getAdapter().getCount() - 1;
    if(position == lastIndex) {
        // Last index is A', we need to scroll to real A, which is at index 1. 
        position = 1;
        circularScroll = true;
    }

    if(circularScroll) {
        final int realPosition = position;
        mPager.postDelayed(new Runnable() {

            @Override
            public void run() {
                mPager.setCurrentItem(realPosition, false);
            }

        }, 500L);
    }
}
Manish Mulimani
  • 17,225
  • 2
  • 37
  • 60
  • Absolutely perfect! Can you explain a little more about this answer? I am sure a lot of people will use this solution! Thanks a lot! – Otuyh Sep 11 '14 at 18:17
0

When you set the second parameter of the setCurrentItem to true it should smooth scroll

@Override
public void onPageScrollStateChanged (int state) {
    if (state == ViewPager.SCROLL_STATE_IDLE) {
        int curr = viewPager.getCurrentItem();
        int lastReal = viewPager.getAdapter().getCount() - 2;
        if (curr == 0) {
            viewPager.setCurrentItem(lastReal, true);
        } else if (curr > lastReal) {
            viewPager.setCurrentItem(1, true);
        }
    }
}
Metehan
  • 693
  • 5
  • 21
  • This is true, but i can't use in this case. I need to manually use the smoothScroll to scroll the rest of pixels left to finish the slide. If i use your solution, when i'll slide from 1 to 0, it will show i'm going to the third page of ViewPager, and i don't want this. More details inside the url that i linked. Thanks anyway! – Otuyh Sep 09 '14 at 13:41