Is there any way to slow the scroll speed with the viewpager adaptor in android?
You know, I've been looking at this code. I can't figure out what I'm dong wrong.
try{
Field mScroller = mPager.getClass().getDeclaredField("mScroller");
mScroller.setAccessible(true);
Scroller scroll = new Scroller(cxt);
Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
scrollDuration.setAccessible(true);
scrollDuration.set(scroll, 1000);
mScroller.set(mPager, scroll);
}catch (Exception e){
Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();
}
It doesn't change anything yet no exceptions occur?
I have used
Here is the example:
Here's an answer using an entirely different approach. Someone might say this has a hacky feel; however, it doesn't use reflection, and I would argue that it will always work.
We find the following code inside
ViewPager.smoothScrollTo
:It calculates the duration based on a few things. See anything we can control?
mAdapter.getPageWidth
. Let's implement ViewPager.OnPageChangeListener in our adapter. We're going to detect when the ViewPager is scrolling, and give a fake value for width. If I want the duration to bek*100
, then I will return1.0/(k-1)
forgetPageWidth
. The following is Kotlin impl of this part of the adapter which turns the duration into 400:Don't forget to add the adapter as an OnPageChangedListener.
My particular case can safely assume that the user can't swipe to drag between pages. If you have to support settling after a drag, then you need to do a bit more in your calculation.
One downside is that this depends on that hardcoded
100
base duration value in ViewPager. If that changes, then your durations change with this approach.I wanted to solve the same issue as all of you and this is my solution for the same problem, but I think this way the solution is more flexible as you can change the duration however you like and also change the interpolation of the values as desired to achieve different visual effects. My solution swipes from page "1" to page "2" , so only in increasing positions, but can easily be changed to go in decreasing positions by doing "animProgress - lastFakeDrag" instead of "lastFakeDrag - animProgress". I think this is the most flexible solution for performing this task.
I have found better solution, based on @df778899's answer and the Android ValueAnimator API. It works fine without reflection and is very flexible. Also there is no need for making custom ViewPager and putting it into android.support.v4.view package. Here is an example: