android当中的Viewpager用作自动滑动的轮播效果时,其滑动速度要比ios快好多,不是很美观。其实v4包里的viewpager已经预留了速度接口,但是并没有对外开放,而写自定义viewpager经笔者测试很不现实,于是只能拿viewpager里面的私有成员Scroller 来开刀。
首先复写scroller这个类的一些重要方法
public class FixedSpeedScroller extends Scroller {
private int mDuration = 400;//自动切换动画的持续时间
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
if (duration % 100 == 0 && duration > 0) {
// JLogUtils.i("robin", "现在是自动划");
if (duration / 100 == eventViewList.size()) {//如果是最后一张
// JLogUtils.i("robin", "现在是最后一张");
super.startScroll(startX, startY, dx, dy, 1);//最后一张快速返回第一张
} else {
super.startScroll(startX, startY, dx, dy, mDuration);
}
} else {
// JLogUtils.i("robin", "现在是手动划" + duration);
super.startScroll(startX, startY, dx, dy, 80);
}
}
}
然后通过反射的方法,换掉viewpager里面原来的Scroller
try {
mField = ViewPager.class.getDeclaredField("mScroller");
mField.setAccessible(true);
mScroller = new FixedSpeedScroller(vpEvent.getContext(), new AccelerateInterpolator());
try {
mField.set(mViewPager, mScroller);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
原来的逻辑不变就可以了。
另外在自动轮播的时候,我们希望当用户手在viewpager上滑动时,自动轮播暂停,下面是和暂停有关的代码
mViewpager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_MOVE:
// Log.i("robin", "down了");
if (!scheduledExecutorService.isShutdown()) {
scheduledExecutorService.shutdown();
}
break;
case MotionEvent.ACTION_UP:
// Log.i("robin", "up了");
if (scheduledExecutorService.isShutdown()) {
// Log.i("robin", "准备开启线程");
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// 当Activity显示出来后,每3秒钟切换一次图片显示
scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 3, 3, TimeUnit.SECONDS);
}
break;
default:
break;
}
return <span style="font-family: Arial, Helvetica, sans-serif;">mViewpager</span>.onTouchEvent(motionEvent);
}
});