系统代码的duration被设置为0,所以不能实现平滑移动
void smoothScrollTo(int x, int y, int velocity) {
if (getChildCount() == 0) {
// Nothing to do.
setScrollingCacheEnabled(false);
return;
}
int sx = getScrollX();
int sy = getScrollY();
int dx = x - sx;
int dy = y - sy;
if (dx == 0 && dy == 0) {
completeScroll(false);
populate();
setScrollState(SCROLL_STATE_IDLE);
return;
}
setScrollingCacheEnabled(true);
setScrollState(SCROLL_STATE_SETTLING);
final int width = getClientWidth();
final int halfWidth = width / 2;
final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width);
final float distance = halfWidth + halfWidth *
distanceInfluenceForSnapDuration(distanceRatio);
int duration = 0;
velocity = Math.abs(velocity);
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
} else {
final float pageWidth = width * mAdapter.getPageWidth(mCurItem);
final float pageDelta = (float) Math.abs(dx) / (pageWidth + mPageMargin);
duration = (int) ((pageDelta + 1) * 100);
}
duration = Math.min(duration, MAX_SETTLE_DURATION);
mScroller.startScroll(sx, sy, dx, dy, duration);
ViewCompat.postInvalidateOnAnimation(this);
}
由于smoothScrollTo方法不能被重写,切方法过于复杂,只能考虑重写mScroller的startScroll方法。
ViewPager对外不提供设置Scroller的方法,只能通过反射设置改对象
public class MyViewPager extends ViewPager {
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setMyScroller();
}
private void setMyScroller() {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new MyScroller(getContext()));
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyScroller extends Scroller {
public MyScroller(Context context) {
super(context, new DecelerateInterpolator());
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, 1000);
}
}
}