mScroller = new Scroller(getContext(), null, true);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() != 2) {
throw new RuntimeException(“Only need two child view! Please check you xml file!”);
}
mLeftView = getChildAt(0);
mRightView = getChildAt(1);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mInitX = ev.getX();
mInitY = ev.getY();
super.dispatchTouchEvent(ev);
return true;
case MotionEvent.ACTION_MOVE:
//>0为手势向右下
mOffsetX = ev.getX() - mInitX;
mOffsetY = ev.getY() - mInitY;
//横向手势跟随移动
if (Math.abs(mOffsetX) - Math.abs(mOffsetY) > ViewConfiguration.getTouchSlop()) {
int offset = (int) -mOffsetX;
if (getScrollX() + offset > mRightView.getWidth() || getScrollX() + offset < 0) {
return true;
}
this.scrollBy(offset, 0);
mInitX = ev.getX();
mInitY = ev.getY();
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
//松手时刻滑动
int offset = ((getScrollX() / (float)mRightView.getWidth()) > 0.5) ? mRightView.getWidth() : 0;
// this.scrollTo(offset, 0);
mScroller.startScroll(this.getScrollX(), this.getScrollY(), offset-this.getScrollX(), 0);
invalidate();
mInitX = 0;
mInitY = 0;
mOffsetX = 0;
mOffsetY = 0;
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
this.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
}
简单吧,使用Scroller就能这么优雅的滑动,不解释,简单的Demo,哈哈;有了这个基本映像我们直接高速——源码探测,搞清源码基本原理流程就能用的顺手喽。
【工匠若水 http://blog.youkuaiyun.com/yanbober 未经允许严禁转载,请尊重作者劳动成果。私信联系我】
3 Scroller源码浅析
==================
通过上面实例我们可以发现在自定义View的过程中使用Scroller的流程如下图所示:
既然有了这么明确的流程图,那我们下面就来依据这个流程简单分析下Scroller的源码。可以发现Scroller这类的代码不多哇,确实是一个工具类,哈哈,我们先看下构造方法:
public Scroller(Context context) {
this(context, null);
}
public Scroller(Context context, Interpolator interpolator) {
this(context, interpolator,
context.getApplicationInfo().targetSdkVersion >= Build.VERSION_