5

根据android培训,如果您扩展GestureDetector.SimpleOnGestureListener和返回false,则永远不会调用onDown(...)其他方法:GestureDetector.SimpleOnGestureListener

无论您是否使用 GestureDetector.OnGestureListener,最好实现一个返回 true 的 onDown() 方法。这是因为所有手势都以 onDown() 消息开头。如果您从 onDown() 返回 false,正如 GestureDetector.SimpleOnGestureListener 默认所做的那样,系统假定您要忽略手势的其余部分,并且永远不会调用 GestureDetector.OnGestureListener 的其他方法。这有可能在您的应用程序中导致意外问题。您应该从 onDown() 返回 false 的唯一情况是您真的想忽略整个手势。

但是,在我的简单测试onScroll(...)中被调用。

public void onCreate(Bundle savedInstanceState) {
    mDetector = new GestureDetectorCompat(this, MyGestureListener);
}


public boolean onTouchEvent(MotionEvent event) { 
    mDetector.onTouchEvent(event);
    return true;
}


class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    private boolean scrollEvent;

    @Override
    public boolean onDown (MotionEvent event) {
        Log.v("GESTURE", "onDown ");
        return false;
    }

    @Override
    public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        Log.v("GESTURE", "onScroll");
        return true;
    }

另一个类似的问题是下一个定义,同样来自同一个 android 培训页面:

单个 on 方法的返回值为 true 表示您已经处理了触摸事件。false 返回值通过视图堆栈向下传递事件,直到成功处理触摸。

这与之前的报价如何解决?

4

3 回答 3

7

您应该从 onDown() 返回 false 的唯一情况是您真的想忽略整个手势。

这几乎说明了一切。

关键是该onDown(...)方法接收 aMotionEvent作为参数,您可以选择分析方法MotionEvent中的onDown(...),如果它不是您想要处理的东西,则返回false

AMotionEvent带有许多详细信息,其中包括手势开始的位置(例如) - 如果它在您要处理的区域之外,则 returnfalse否则 return true

如果您trueonDown(...)其他方法返回,则将被调用。这些方法中的每一个都可以选择分析和处理传递给它们的各种参数。如果您在任何这些方法中处理事件并且不想要任何进一步的操作,则从这些方法返回 true,否则将调用其他方法(可能在超类中,具体取决于您的代码实现)。

手势很复杂,涉及上下动作以及任何方向的运动。允许选择拒绝手势(通过返回falseonDown(...)使事情变得更加通用。

编辑:在某些情况下,您可能会在屏幕上有多个视图。MotionEvent传递给onDown(...)将包含有关手势开始位置的信息。如果您不希望屏幕的某些区域对手势做出反应,则false在检查手势的起始位置后返回。

于 2014-04-17T01:06:38.827 回答
0

实际上,我不知道它是否正确,但在这种情况下这个定义会正确

例如,您处理 onTouch TextViewTextView默认为not clickable

class MainActivity : AppCompatActivity() {
    private lateinit var detector: GestureDetectorCompat

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        detector = GestureDetectorCompat(this, MyGestureListener())


        findViewById<View>(R.id.textview).setOnTouchListener { v, event ->
            // 
            // Don't always return true here (like OP post)
            // 
            detector.onTouchEvent(event) // Kotlin code, equivalent to "return detector.onTouchEvent(event)" in Java
        }
    }

    inner class MyGestureListener : GestureDetector.SimpleOnGestureListener() {

        override fun onDown(event: MotionEvent): Boolean {
            Log.d(DEBUG_TAG, "onDown: " + event.toString())
            return false
        }

        override fun onFling(event1: MotionEvent, event2: MotionEvent,
                         velocityX: Float, velocityY: Float): Boolean {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString())
            return true
        }

        override fun onSingleTapUp(event: MotionEvent?): Boolean {
            Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString())
            return true
        }
    }
}

在这种情况下:
如果您的onDown函数返回FALSE,则打开onFling并且onSingleTapUp 从不调用

如果你的onDown函数返回TRUE, ononFlingonSingleTapUp CAN调用

笔记

如果视图是 ,则此定义将更正not clickable。如果
视图是clickable, ALL事件将被调用或者onDown return falseonDown return true

希望对您有所帮助,如果我错了,请纠正我 DEMO

于 2018-08-16T09:36:22.990 回答
0

我不确定我是对还是错,但以下是用户应该从 onDown() 返回 false 的点

  1. 当用户不想对屏幕上的手势做出反应时。
  2. 当用户想要实现或使用触摸事件的 onLongPress() 方法时。

对于第 1 点,@Squonk 和 @Phan Van Linh 都提供了解释,所以我只解释第 2 点。

第 2 点:当用户想要实现 onLongPress() 方法时。

public MySurfaceView(Context context, IAttributeSet attrs):base(context, attrs)
{
    this.context=context;
    SetWillNotDraw(false);
    gestureDetector = new GestureDetector(context, new GestureListener());

}

 public override bool OnTouchEvent(MotionEvent e)
{
    Log.Debug(Tag, "Inside" + System.Reflection.MethodBase.GetCurrentMethod().Name + "Method");
    return gestureDetector.OnTouchEvent(e); 
}

private class GestureListener : GestureDetector.SimpleOnGestureListener
{
    public override bool OnDown(MotionEvent e)
    {
        Log.Debug("Tag", "Inside Gesture OnDown Event");
        // don't return false here or else none of the other 
        // gestures will work
        return true;

    }

    public override bool OnSingleTapConfirmed(MotionEvent e)
    {
        Log.Debug("Tag", "Inside Gesture OnSingleTapConfirmed Event");

        return true;
    }

    public override bool OnDoubleTap(MotionEvent e)
    {
        Log.Debug("Tag", "Inside Gesture OnDoubleTap Event");
        return true;
    }

    public override void OnLongPress(MotionEvent e)
    {
        Log.Debug("Tag", "Inside Long Press Event");
    }




}

如果您在 OnDown 方法中返回 True,则 GestureListener 类的所有方法都将被调用,除了 onLongPress()

如果在 OnDown 方法中返回 false,则只会调用 onLongPress 方法。

让我知道我的观察是否错误。

于 2018-10-11T04:04:59.167 回答