如何在Android中的视图中添加手势检测器

Sur*_*gch 20 android touch-event gesturedetector

我正在努力为我的项目中的子视图添加手势检测器.我是否会覆盖父母onTouchEvent或孩子的onTouchEvent?我OnTouchListener在那里制作并添加手势探测器吗?该文档显示如何将手势检测器添加到活动本身一个例子,但它是不明确如何将它添加到一个视图.如果继承视图(例如此处),则可以使用相同的过程,但我想添加手势而不进行任何子类化.

是我能找到的最接近的其他问题,但它特定于一个fling手势ImageView,而不是任何一般情况View.关于什么时候回来true或者回答这些答案还有一些分歧false.

为了帮助自己了解它是如何工作的,我做了一个独立的项目.我的答案如下.

Sur*_*gch 45

此示例显示如何向视图添加手势检测器.布局只是ViewActivity 的一个内部.您可以使用相同的方法将手势检测器添加到任何类型的视图.

在此输入图像描述

我们将手势检测器添加到绿色View.

MainActivity.java

基本思想是OnTouchListener在视图中添加一个.通常我们会得到这里所有的未经处理的触摸数据(如ACTION_DOWN,ACTION_MOVE,ACTION_UP,等),但不是处理它自己,我们会将其转发到一个姿态探测器做触摸数据的解释.

我们正在使用SimpleOnGestureListener.关于这个手势检测器的好处是我们只需要覆盖我们需要的手势.在这里的例子中,我包含了很多.您可以删除不需要的那些.(你应该总是返回trueonDown(),但是,回到我们正在处理事件的真正手段.返回false将使系统停止给我们更多的触摸事件.)

public class MainActivity extends AppCompatActivity {

    private GestureDetector mDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // this is the view we will add the gesture detector to
        View myView = findViewById(R.id.my_view);

        // get the gesture detector
        mDetector = new GestureDetector(this, new MyGestureListener());

        // Add a touch listener to the view
        // The touch listener passes all its events on to the gesture detector
        myView.setOnTouchListener(touchListener);
    }

    // This touch listener passes everything on to the gesture detector.
    // That saves us the trouble of interpreting the raw touch events 
    // ourselves.
    View.OnTouchListener touchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // pass the events to the gesture detector
            // a return value of true means the detector is handling it
            // a return value of false means the detector didn't 
            // recognize the event
            return mDetector.onTouchEvent(event);

        }
    };

    // In the SimpleOnGestureListener subclass you should override 
    // onDown and any other gesture that you want to detect.
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d("TAG","onDown: ");

            // don't return false here or else none of the other 
            // gestures will work
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.i("TAG", "onSingleTapConfirmed: ");
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.i("TAG", "onLongPress: ");
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.i("TAG", "onDoubleTap: ");
            return true;
        }

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

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                               float velocityX, float velocityY) {
            Log.d("TAG", "onFling: ");
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个快速设置来运行这个项目,所以我建议你尝试一下.请注意日志事件的发生方式和时间.


Pal*_*dro 7

Kotlin中的短版,仅检测视图时双击:

val gestureDetector = GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() {
    override fun onDoubleTap(e: MotionEvent?): Boolean {
        Log.d("myApp", "double tap")
        return true
    }
})
myView.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }
Run Code Online (Sandbox Code Playgroud)

而且不要忘了myView点击

  • 谢谢。一个小修正: onDown() 需要被覆盖并返回 true 否则它不会工作 (2认同)