我使用类似于以下的代码在 Android 上实现了一个简单的可滚动画廊类型视图:
private int mPos; // The current scroll position.
private int mLastMostionPos; // Previous touch position.
@Override
public boolean onTouchEvent(MotionEvent ev)
{
final int action = ev.getAction();
Log.d(TAG, "Mouse mLastMotionPos: " + mLastMotionPos + " ev.getX(): " + ev.getX() + " mPos: " + mPos + " ev.getPointerId(0): " + ev.getPointerId(0)
+ " ev.getEventTime(): " + ev.getEventTime());
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
// Remember where the motion event started
mLastMotionPos = (int)ev.getX();
break;
case MotionEvent.ACTION_MOVE:
final int pos = (int)ev.getX(activePointerIndex);
// Scroll to follow the motion event
int delta = mLastMotionPos - pos;
mLastMotionPos = pos;
mPos += delta;
if (mPos < mMinPos)
mPos = mMinPos;
if (mPos > mMaxPos)
mPos = mMaxPos;
break;
它有效,但我注意到有时它会突然“跳跃”一点。只有当您滚动到一端时,它才会真正引人注目。如果您已经一直向右滚动,并且您的手指总是向右移动,则有时该事物会向左跳一帧。
我在上面添加了日志记录行并获得了这个输出(为便于阅读而编辑):
50.913: Mouse mLastMotionPos: 304 ev.getX(): 379.0 mPos: 0 ev.getPointerId(0): 0 ev.getEventTime(): 111690077
50.928: Mouse mLastMotionPos: 379 ev.getX(): 369.0 mPos: 0 ev.getPointerId(0): 0 ev.getEventTime(): 111690093
50.943: Mouse mLastMotionPos: 369 ev.getX(): 384.0 mPos: 10 ev.getPointerId(0): 0 ev.getEventTime(): 111690109
50.958: Mouse mLastMotionPos: 384 ev.getX(): 391.0 mPos: 0 ev.getPointerId(0): 0 ev.getEventTime(): 111690125
50.983: Mouse mLastMotionPos: 391 ev.getX(): 399.0 mPos: 0 ev.getPointerId(0): 0 ev.getEventTime(): 111690141
51.023: Mouse mLastMotionPos: 399 ev.getX(): 399.0 mPos: 0 ev.getPointerId(0): 0 ev.getEventTime(): 111690186
请注意,它会跳跃 10 个像素!我发誓我只是将手指向右拖动,并且非常慎重。起初我认为 Android 可能会乱序传递事件或其他什么,但事件时间是单调的。
知道为什么会这样吗?我想这可能是三星的错(我有 Galaxy S2)。它确实有一个延迟驱动程序强加的触摸阈值,因此编写输入驱动程序的人显然不知道他们在做什么。尽管如此,10 像素似乎是一个很大的飞跃。有时它甚至更大!