1

我使用类似于以下的代码在 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 像素似乎是一个很大的飞跃。有时它甚至更大!

4

4 回答 4

2

稍晚一点,但也许它对其他人有用,如果您只对延迟感兴趣而不对实际的 MotionEvent 位置感兴趣,您可以使用 getRawX() 和 getRawY() 方法。我遇到了完全相同的问题,我改变了获取坐标的方式,瞧!它正在工作。

于 2015-02-16T16:32:31.247 回答
0

我不知道这背后的确切逻辑,但我遇到了同样的问题

这个问题与“硬件”无关,因为我已经在3 种不同的设备上进行了测试(一个是索尼,另外两个是三星的),但它在任何地方都给出了相同的结果..即使在模拟器上它的行为也一样......

在“垂直滑动”的情况下,我正面临着它。虽然我滑动了几个像素,但它给出了 150 像素(或更大)的巨大差异。

我几乎厌倦了这种奇怪的跳跃

但是当我在我的“Demoapplication”中复制相同的代码以便使用它时,它在那里就像一个魅力。

解决方案 :-

我刚刚从我的 XML 布局中替换ScrollView(这是我用于滑动的父布局,也可能是问题背后的唯一原因),然后一切都被排序了......

我希望ScrollView也是你案件的罪魁祸首。

顺便说一句,我使用它作为参考来在我的代码中实现滑动。

于 2013-03-06T10:22:41.340 回答
0

我遇到了类似的问题。对我来说,事实证明我正在从我的事件处理程序中保存一个 MotionEvent 并稍后重新发布它。这很糟糕,因为 MotionEvents 被强制垃圾收集。如果要制作副本,则需要像这样制作副本:

val copy = MotionEvent.obtain(event)

如果您确实制作了这样的副本,请不要忘记在完成后自己回收它:

copy.recycle()
于 2020-01-02T05:37:13.330 回答
-1

可能与硬件有关?您是否尝试过更强大的设备?

于 2012-10-16T11:05:09.037 回答