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