Scroller用于View的滑动,其基本原理还是ScrollTo/ScrollBy。Scroller在其基础上把滑动的位移切分成无数细小的单元,并在一个时间段内对其进行位移,使View的滑动看起来具有平滑的效果。
Scroller的一般使用要结合View的ComputeScroll方法。这个方法默认会在View的draw方法(我们一般重写的是onDraw方法,不是draw方法)中调用。draw方法会在我们调用invalidate方法后对View进行重新绘制。利用这个特性可以完成多段位移。
public class ScrollButton extends android.support.v7.widget.AppCompatButton {
Scroller scroller;
int direction = -1;
public ScrollButton(Context context) {
this(context,null);
}
public ScrollButton(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ScrollButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
scroller = new Scroller(context);
}
@Override
public void computeScroll() {
if(scroller!=null){
if(scroller.computeScrollOffset()){//判断scroll是否完成
((View) getParent()).scrollTo(
scroller.getCurrX(),scroller.getCurrY()
);//执行本段位移
invalidate();//进行下段位移
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
scroller.startScroll(((int) getX()), ((int) getY()), ((int) getX())*direction,
((int) getY())*direction);//开始位移,真正开始是在下面的invalidate
direction*=-1;//改变方向
invalidate();//开始执行位移
break;
}
return super.onTouchEvent(event);
}
}
上面自定义了一个按钮,并且按下按钮会让按钮进行一段平滑的位移。要使用这个按钮,只需要在xml文件中声明即可,无需其他步骤。
下面来看一下不借助View的ComputeScroll来使用Scroller。当然这里只是为了加深理解,大多数Scroller还是要结合View的ComputeScroll方法的。
final Scroller scroller = new Scroller(this);
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(scroller.computeScrollOffset()){
((View) tv1.getParent()).scrollTo(
scroller.getCurrX(),scroller.getCurrY()
);
sendEmptyMessage(0);
}
}
};
tv1.setOnClickListener(new View.OnClickListener() {//tv1是一个TextView
@Override
public void onClick(View v) {
scroller.startScroll(0, 0, 100,
100);
handler.sendEmptyMessage(0);
}
});
可以看到,也是利用了handler的循环发消息的特点来完成scroll。那么在这里可以总结一下,Scroller其实只提供了一个拆分位移的功能,不过还是结合View的ComputeScroll来使用最好,可以完成合理的控件封装。