弹性滑动
弹性滑动的共同思想:将一次打的滑动分为若干次小的滑动并在一个时间段内完成。
使用Scroller
前面讲过用法了,Scroller本身不能实现view滑动,关键在于startScroll后的重新绘制,会在draw里面去调用computeScroll,再次执行获取x\y去执行滑动重绘。设计很巧妙,没有对view的依赖,也没有定时器的使用。
private final Scroller mScroller;
public ViewDemo(Context context) {
super(context);
mScroller = new Scroller(context);
}
public void smoothScrollerTo(int destX, int destY) {
int scrollX=mScroller.getCurrX();
int delta=destX-scrollX;
//1000ms慢慢滑动向delta
mScroller.startScroll(scrollX,0,delta,0,1000);
//绘制
invalidate();
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()){
smoothScrollerTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
通过动画
动画本身就是一种渐进的过程
ObjectAnimator.ofFloat(getRootView(),"translationX",0,100).setDuration(100).start();
当然也可以模仿Scroller来实现滑动
ValueAnimator animator = ValueAnimator.ofFloat(m.progress, progress);
animator.addUpdateListener(animation -> {
float animatedValue = (float) animation.getAnimatedValue();
mButton.scrollTo(startX+animatedValue,0);
});
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(animTime);
animator.start();
使用延迟策略
定时刷新View,具体可以是Handler或View的POSTDelay方法,也可以使用线程的sleep,或者定时器之类延迟。
private static int count=0;
private static Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what){
case 0:
count++;
mButton.scrollTo(count*100,0);
handler.sendEmptyMessageDelayed(0,30);
break;
}
}
};