弹性滑动的思想:将一次大的滑动分成若干次小的滑动并在一个时间段内完成。
1.1、使用Scroller
Scroller的使用方法:
Scroller scroller = new Scroller(mContext);
//缓慢滚动到指定位置
private void smoothScrollTo(int destX ,int destY){
int scrollX = getScrollX(); //View的内容X轴已经滑动的距离
int deltaX = destX - scrollX ; //View的内容要滑动的距离
scroller.startScroll(scrollX , 0 ,deltaX , 0 ,1000);
invalidate() ;
}
我的理解 这里的destX ,destY都是通过getX()和getY()获取的是相对于View本身的坐标。每次滑动后,坐标轴(0,0)位置相对于View本身的位置就会发生改变。实际上就是ScrollTo时参数的计算方法。如下图
@override
public void computeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();
}
}
Scroller如何让View弹性滑动的?startScroll()——>invalidate()——>导致View重绘(1)——>调用computeScroll——>调用scrollTo()——>调用 postInvalidate() ——>重复(1)和之后的过程。
mScroller.computeScrollOffset()方法会根据时间流逝来计算当前的scrollX和scrollY的值,返回true表示滑动还未结束。
1.2、通过动画
动画本身就是一种渐近的过程,因此通过它来实现的滑动天然就具有弹性效果。
利用动画的延时特性,模仿Scroller来实现View的弹性滑动。
final int startX=0 ; final int delatX = 100 ;
ValueAnimator animator = ValueAnimator.ofInt(0,1).setDuration(1000);
animatar.addUpdateListener(new AnimatorUpdateListener(){
@Override
public void onAnimationUpdate( ValueAnimator animator ){
val animatedFraction = animatar.getAnimatedFraction();
textView.scrollTo(startX +(int)(deltaX *animatedFraction),0);
}
}
animatar.start();
我们的动画本质上没有作用在任何对象上,他只是在1000ms完成整个动画过程。
我们可以在动画的每一帧到来时获取动画完成的比例。然后根据这个比例计算View要滑动的距离。
1.3、使用延时策略:Handler 或者 View的postDelayed()