GestureDetector类

作者: 祭清明樱花 | 来源:发表于2016-03-08 15:40 被阅读0次
    • GestureDetector为手势识别类,用来监听回调用户对视图的操作。
      这次我们就分别模拟一些用户的手势事件,来看看这个类是怎么回调的吧
      废话不多说,直接看代码。
      public class MainActivity extends AppCompatActivity {
      private Button mButton;
      private GestureDetector mGestureDetector;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.button);
      mGestureDetector = new GestureDetector(this, new MyOnGestureListener());
      mButton = (Button) findViewById(R.id.btn_textgesture);
      mButton.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
      Log.i(getClass().getName(), "onTouch-----" +
      getActionName(event.getAction()));
      mGestureDetector.onTouchEvent(event);
      // 一定要返回true,不然获取不到完整的事件
      return true;
      }
      });
      }
      private String getActionName(int action) {
      String name = "";
      switch (action) {
      case MotionEvent.ACTION_DOWN: {
      name = "ACTION_DOWN";
      break;
      }
      case MotionEvent.ACTION_MOVE: {
      name = "ACTION_MOVE";
      break;
      }
      case MotionEvent.ACTION_UP: {
      name = "ACTION_UP";
      break;
      }
      default:
      break;
      }
      return name;
      }
      class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener {
      @Override
      public boolean onSingleTapUp(MotionEvent e) {
      Log.i(getClass().getName(), "onSingleTapUp-----" +
      getActionName(e.getAct ion()));
      return false;
      }
      @Override
      public void onLongPress(MotionEvent e) {
      Log.i(getClass().getName(), "onLongPress-----" +
      getActionName(e.getAction()));
      }
      @Override
      public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {
      Log.i(getClass().getName(),"onScroll-----" +
      getActionName(e2.getAction()) + ",(" + e1.getX() + "," +
      e1.getY() + ") ,("+ e2.getX() + "," + e2.getY() + ")");
      return false;
      }
      @Override
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
      Log.i(getClass().getName(),"onFling-----" +
      getActionName(e2.getAction()) + ",(" + e1.getX() + "," + e1.getY()
      + ") ,("+ e2.getX() + "," + e2.getY() + ")");
      return false;
      }
      @Override
      public void onShowPress(MotionEvent e) {
      Log.i(getClass().getName(), "onShowPress-----" +
      getActionName(e.getAction()));
      }
      @Override
      public boolean onDown(MotionEvent e) {
      Log.i(getClass().getName(), "onDown-----" +
      getActionName(e.getAction()));
      return false;
      }
      @Override
      public boolean onDoubleTap(MotionEvent e) {
      Log.i(getClass().getName(), "onDoubleTap-----" +
      getActionName(e.getAction()));
      return false;
      }
      @Override
      public boolean onDoubleTapEvent(MotionEvent e) {
      Log.i(getClass().getName(), "onDoubleTapEvent-----" +
      getActionName(e.getAction()));
      return false;
      }
      @Override
      public boolean onSingleTapConfirmed(MotionEvent e) {
      Log.i(getClass().getName(), "onSingleTapConfirmed-----" + getActionName(e.getAction()));
      return false;
      }
      }
      }

    视图的样子就是一个空布局里面有一个button,准备工作都做好了。

    • 我们来模拟一下单次点击事件:
    单次点击Log
    这里由于笔者点击时抖动了一下,所以多调用了一次<code>onTouch</code>这并不影响我们观察,根据Log的顺序分析,首先调用了<code>onTouch</code>Motion是Down,之后马上调用<code>onDown</code>,Motion同上,这时我们应该把抬起来了,所以调用了<code>onTouch</code>而Motion是Up,最后调用<code>onSingleTapUp</code>是一次单击事件,而最后那个<code>onSingleTapComfirmed</code>方法是用来判断这就是一次点击,一旦调用这个方法,后面就不会出现两次点击(双击)这样的事件
    ,这里笔者有个问题:为什么调用<code>onSingleTapComfirmed</code>的Motion是Down而不是Up?
    如果哪位大神指导这个问题,麻烦在评论区指点下,谢啦。
    • 之后我们模拟一下双击的事件:


      双击Log

      这里依旧出现了Move的Motion...还是不影响观察,继第一次点击之后观察,<code>onTouch</code>依旧调用这里就不再说了,注意下<code>onDoubleTap</code>他在我们按下去的时候就已经调用了,之后的方法<code>onDoubleTapEvent</code>就可以用来监听从双击第二次Down到第二次Up的所有事件。而且,如果调用了<code>onDoubleTap</code>,那之后就不能再调用<code>onSingleTapUp</code>和<code>onSingleTapComfirmed</code>了。

    • 接下来是长按效果的模拟:

    长按Log

    前面的都是一样的,从<code>onShowPress</code>开始,这个是一个按下不滑动时的调用,如果按的时间再长一点就会调用<code>onLongPress</code>这就是长按的实现。值得一提的是,如果长按执行了,直到用户Up,其他的事件都不会触发,如图就是笔者长按后移动后的Log。

    • 再来是移动的模拟:
    移动Log

    这里根据打印的Log可以发现,调用了<code>onScroll</code>,这个方法获取的坐标指的不是滑动的距离,而是距离上一次滑动的坐标。这里说的一次滑动指的是一整个事件。最后的<code>onFling</code>这个字面意思是“抛”,就是滑动后没有停下就离开屏幕,如果不想调用这个方法,在滑动之后要停一下,亲测有效。

    • 最后一点值得注意的是,这些方法除了<code>onLongPress</code>没有返回值,其他的方法都有返回值通过<code>onTouchEvent</code>返回至<code>onTouch</code>。

    理解这个类的事件回调顺序后,相信以后对用户的交互事件处理有点帮助。

    相关文章

      网友评论

        本文标题:GestureDetector类

        本文链接:https://www.haomeiwen.com/subject/sajzkttx.html