我没有使用 OpenGL 和加速计的经验,但是滑动(在 Android 的 API 中称为 fling)并不难实现。制作这样的自定义 View 时,您需要做的第一件事是实现 GestureDetector 并在视图的 onTouchEvent() 中调用它的 onTouchEvent()
GestureDetector mGD = new GestureDetector(getContext(),
new SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// beware, it can scroll to infinity
scrollBy((int)distanceX, (int)distanceY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY) {
mScroller.fling(getScrollX(), getScrollY(),
-(int)vX, -(int)vY, 0, (int)mMaxScrollX, 0, (int)mMaxScrollY);
invalidate(); // don't remember if it's needed
return true;
}
@Override
public boolean onDown(MotionEvent e) {
if(!mScroller.isFinished() ) { // is flinging
mScroller.forceFinished(true); // to stop flinging on touch
}
return true; // else won't work
}
});
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGD.onTouchEvent(event);
}
虽然OnGestureListener.onScroll() 直接调用View.scrollBy(),但对于onFling() 方法,您需要Scroller。
Scroller 是一个简单的对象,正如参考所说,它封装了滚动。它可用于连续滚动或对投掷做出反应。 Scroller.fling() 开始在自身内部“模拟”滚动滚动,通过观察它,您可以通过连续重绘动画复制其平滑度:
@Override
protected void onDraw(Canvas canvas) {
// ....your drawings....
// scrollTo invalidates, so until animation won't finish it will be called
// (used after a Scroller.fling() )
if(mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
}
}
也就是说,直到动画开始运行,计算我们到达的点并滚动到那里。
最后一点:记得在你的OnGestureListener.onDown() 中返回true,即使你不想做任何事情,否则它不会起作用。
并且要小心,因为 Android 2.2 中的 Scroller 有一个错误,即使它达到了您作为参数传递的限制(但计算出的偏移量尊重它们,所以它实际上不会移动) )。