在上一篇我介绍过Scroller类中常用的两个方法scrollTo和scrollBy,如果你还不太清楚这两个方法的用法,你可以去看一下《Android Scroller入门之ScrollTo、ScrollBy》,这篇博客要介绍一下关于Scroller类的简单使用。
首先介绍一下要使用到的API
getFinalX:返回滚动结束位置(得到当前X距离原始位置的值).仅针对"fling"滚动有效.
getCurrX:返回当前滚动 X方向的偏移
invalidate方法和postInvalidate方法:invalidate()在UI线程自身中使用;postInvalidate()在非UI线程中使用.
startScroll(int startX, int startY, int dx, int dy, int duration): 第一,二个参数起始位置;第三,四个滚动的偏移量;第五个参数持续时间
我们先来看一下Scroller的绘制流程
下面通过一个小Demo来讲解,先看一下效果图
1. 自定义类集成LinearLayout,重写构造方法并初始化Scroller和手势识别GestureDetector
private Scroller mScroller;
private GestureDetector mGestureDetector;
public ScrollerLinearLayout(Context context) {
this(context, null);
}
public ScrollerLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ScrollerLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setClickable(true);
setLongClickable(true);
mScroller = new Scroller(context);
mGestureDetector = new GestureDetector(context, new MyGestureListener());
}
2,手指按下并滚动
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
int disY = (int) ((distanceY - 0.5) / 2);
beginScroll(0, disY);
return false;
}
}
//设置滚动的相对偏移
protected void beginScroll(int dx, int dy) {
//第一,二个参数起始位置;第三,四个滚动的偏移量
mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
//必须执行invalidate()从而调用computeScroll()
invalidate();
}
3,调用invalidate方法会触发computeScroll方法的调用,只要computeScrollOffset方法返回false,就标志滚动没有结束
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
super.computeScroll();
}
4.以上逻辑是处理手指按下的逻辑,手指抬起的逻辑我们可以重写onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
//手指抬起时回到最初位置
prepareScroll(0, 0);
break;
default:
//其余情况交给GestureDetector手势处理
return mGestureDetector.onTouchEvent(event);
}
return super.onTouchEvent(event);
}
5.获取到我们抬起是的最终位置,从这里开始回滚
//滚动到目标位置
protected void prepareScroll(int fx, int fy) {
int dx = fx - mScroller.getFinalX();
int dy = fy - mScroller.getFinalY();
beginScroll(dx, dy);
}
这样就完成整个效果了。