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

时间:2017-07-12 10:18:21

标签: android ontouchevent gesturedetector

我在为项目中的子视图添加手势检测器时遇到了困难。我是否会覆盖父onTouchEvent或孩子的onTouchEvent?我是否制作OnTouchListener并在那里添加手势检测器? documentation显示了如何向活动本身添加手势检测器的示例,但不清楚如何将其添加到视图中。如果继承视图(例如here),则可以使用相同的过程,但我想添加手势而不进行任何子类化。

This是我能找到的最接近的其他问题,但它特定于ImageView上的投掷手势,而不是任何View的一般情况。关于何时返回truefalse的答案也存在一些分歧。

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

2 个答案:

答案 0 :(得分:33)

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

enter image description here

我们会将手势检测器添加到绿色ACTION_DOWN

MainActivity.java

基本思路是在视图中添加OnTouchListener。通常情况下,我们会在此处获取所有原始触摸数据(例如ACTION_MOVEACTION_UPtrue等),但我们不会自行处理,而是将其转发给手势检测器对触摸数据进行解释。

我们正在使用SimpleOnGestureListener。关于这个手势检测器的好处是我们只需要覆盖我们需要的手势。在这里的例子中,我包含了很多。您可以删除不需要的那些。 (你应该总是在onDown()中返回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; } } } 。返回true表示我们正在处理该事件。返回false将使系统停止向我们提供更多触摸事件。)

  original =
    one:
      one: 1
    two: 2

  test = ({one, two}) ->
    one.two = two
    {one,two}

  console.log original # original.one has already beed updated!! see mu's comment. 

  destructured = test original

  console.log destructured is original, original.one is destructured.one
  # false true



{
  "one": {
    "one": 1,
    "two": 2
  },
  "two": 2
}

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

答案 1 :(得分:5)

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) }

不要忘记使myView可点击