ViewPagerCustomDuration vp = (ViewPagerCustomDuration) findViewById(R.id.myPager);
vp.setScrollDurationFactor(2); // make the animation twice as slow
ViewPagerCustomDuration.java:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.animation.Interpolator;
import java.lang.reflect.Field;
public class ViewPagerCustomDuration extends ViewPager {
public ViewPagerCustomDuration(Context context) {
super(context);
postInitViewPager();
}
public ViewPagerCustomDuration(Context context, AttributeSet attrs) {
super(context, attrs);
postInitViewPager();
}
private ScrollerCustomDuration mScroller = null;
/**
* Override the Scroller instance with our own class so we can change the
* duration
*/
private void postInitViewPager() {
try {
Field scroller = ViewPager.class.getDeclaredField("mScroller");
scroller.setAccessible(true);
Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
mScroller = new ScrollerCustomDuration(getContext(),
(Interpolator) interpolator.get(null));
scroller.set(this, mScroller);
} catch (Exception e) {
}
}
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor) {
mScroller.setScrollDurationFactor(scrollFactor);
}
}
ScrollerCustomDuration.java:
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;
public class ScrollerCustomDuration extends Scroller {
private double mScrollFactor = 1;
public ScrollerCustomDuration(Context context) {
super(context);
}
public ScrollerCustomDuration(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@SuppressLint("NewApi")
public ScrollerCustomDuration(Context context, Interpolator interpolator, boolean flywheel) {
super(context, interpolator, flywheel);
}
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor) {
mScrollFactor = scrollFactor;
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, (int) (duration * mScrollFactor));
}
}
public class PresentationViewPager extends ViewPager {
public static final int DEFAULT_SCROLL_DURATION = 250;
public static final int PRESENTATION_MODE_SCROLL_DURATION = 1000;
public PresentationViewPager (Context context) {
super(context);
}
public PresentationViewPager (Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setDurationScroll(int millis) {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new OwnScroller(getContext(), millis));
} catch (Exception e) {
e.printStackTrace();
}
}
public class OwnScroller extends Scroller {
private int durationScrollMillis = 1;
public OwnScroller(Context context, int durationScroll) {
super(context, new DecelerateInterpolator());
this.durationScrollMillis = durationScroll;
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, durationScrollMillis);
}
}
}
7条答案
按热度按时间ymdaylpp1#
我想做自己,并实现了一个解决方案(使用反射,但是).我还没有测试它,但它 * 应该 * 工作或需要最小的修改.测试Galaxy Nexus JB 4.2.1.你需要在您的XML中使用
ViewPagerCustomDuration
而不是ViewPager
,然后你可以这样做:ViewPagerCustomDuration.java
:ScrollerCustomDuration.java
:cld4siwp2#
基于@df778899的答案和Android ValueAnimator API,我找到了更好的解决方案。它可以很好地工作,没有反射,非常灵活。也不需要定制ViewPager并将其放入android.support.v4.view包中。下面是一个示例:
更新:
刚刚检查了此解决方案是否可用于一次滑动多个页面(例如,如果第一页应显示在最后一页之后)。这是稍微修改的代码,以处理指定的页数:
myss37ts3#
pvabu6sv4#
更好的解决方案是通过在支持包中创建类来访问私有字段。EDIT这与
MAX_SETTLE_DURATION
的600ms绑定,由ViewPager
类设置。当然,您可以添加一个自定义属性,以便通过XML进行设置。
ep6jt1vc5#
下面是我在Librera Reader中使用的代码
ltskdhd16#
我使用Cicero莫拉的版本制作了一个Kotlin类,它在Android 10中仍然可以完美地工作。
正在从活动类初始化:
6ju8rftf7#
在浪费了一整天之后,我找到了一个解决方案,将offscreenPageLimit设置为页面总数。
为了保持ViewPager平滑滚动的恒定长度,setOffScreenLimit(page.length)将把所有视图保存在内存中。但是,这会给任何涉及调用View.requestLayout函数的动画带来问题(例如,任何涉及对边距或边界进行更改的动画)。这会使它们变得非常慢(根据Romain Guy的说法)因为内存中的所有视图也会失效,所以我尝试了几种不同的方法来使事情顺利进行,但是覆盖requestLayout和其他失效方法会导致许多其他问题。
一个很好的折衷方案是动态修改离屏限制,这样页面之间的大部分滚动都将非常平滑,同时通过删除视图来确保所有页面内动画的平滑。当你只有1或2个视图时,这会非常有效,因为其他视图将不得不从内存中删除。
***在没有任何解决方案起作用时使用此选项,因为通过设置offsetlimit,u将同时加载所有片段