View有scrollTo、scrollBy方法,但是滑动是瞬时的,比较僵硬。可以通过Scroller来实现View的弹性滑动。
ScrollView就有smoothScrollTo和smoothScrollBy方法,这两个方法实现的就是弹性滑动的效果,它们内部实际也是用了Scroller。
Scroller的典型使用方法:
private Scroller mScroller = new Scroller(getContext());
private void smoothScrollTo(int destX, int destY, int scrollTime){
mScroller.startScroll(getScrollX(), getScrollY(), destX - getScrollX(), destY - getScrollY(), scrollTime);
invalidate();
}
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
上述代码就能实现慢慢滑动的弹性效果,为什么呢?
从源码看,startScroll这个方法内部其实什么也没有做,只是保存了传递的参数:
invalidate方法会使view重绘,view的draw方法会去调用computeScroll方法,我们复写了这个方法,在里面调用了computeScrollOffset,这个函数的意义是根据当前时间的流逝计算出当前的scrollX和scrollY应该是多少(根据之前startScroll所传入的时间),如果这个方法返回true,证明滑动还没有结束。所以只要判断还在滑动,就调用scrollTo,滑动到当前的scrollX和scrollY的位置,然后再调用postInvalidate,又会使得view重绘,然后再次调用computeScroll方法,直到computeScrollOffset返回false滑动结束。
因此,Scroller本身其实并不能使view滑动,还需配合view的computeScroll方法才能实现。