美文网首页android学习笔记
android事件分发学习笔记

android事件分发学习笔记

作者: heheworld | 来源:发表于2020-03-22 16:40 被阅读0次
  1. 事件分发的载体主要有 activity,viewgroup,view。
  2. 事件分发的主要方法有 dispatchTouchEvent (事件分发),onInterceptTouchEvent(事件拦截),onTouchEvent(事件响应),
    • 关于返回值

    是boolean类型,如果返回true,表示事件被消费,不再往下一级传递,否则继续传递。如果都没有消费,最终会回到activity的onTouchEvent。

    • 关于onInterceptTouchEvent

    是viewgroup所特有的。

  3. 事件分发的对象是 MotionEvent 。
  4. 事件的序列,常见的就是action_down,move,up,cancel等等,
  • 如果一个view决定拦截,那么着一个序列的事件都会交由它来处理,同时down事件以外的事件也不再调用onInterceptTouchEvent方法。
  • 正常情况下一个事件序列的事件不会分由两个view处理(通过ontouchevent强行传递给其他view的另说)
  • 如果view 不消费除down以外的事件,该事件会消失。
  • 如果view拦截后,但是什么事件都不处理,该事件会交由它的父view处理。
  1. 事件分发的流程 从activity的dispatchTouchEvent开始,经过phonewindow,decorview,调用到viewgroup的dispatchTouchEvent方法,然后在这个方法里,根据Intercept的值,事件的action,以及对应的childview(根据点击的坐标,从上至下的顺序 获取Z坐标上的view的列表,再依据view的dispatchTouchEvent返回值,返回愿意消费此事件的childview),事件就这样被传递出去。
    例子,viewgroup如果拦截某事件,则直接调用viewgroup的onTouchEvent,
    如果不拦截某事件,则交由子view处理,调用子view的dispatchTouchEvent,然后再调用子view的onTouchEvent。
  2. 关于触摸事件跟点击事件的冲突,如果onTouchEvent 返回true 则事件被消费,不会再响应点击事件。只有返回false,才可以。
  3. 关于滑动冲突,可以通过外部拦截和内部拦截两种方式。
外部拦截,

重写父view的onInterceptTouchEvent 方法
伪代码

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        boolean intercept = false;
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                intercept = false;
                break;
                case MotionEvent.ACTION_MOVE:
                    if(需要拦截)
                    {
                        intercept = true;
                    }
                    else
                    {
                        intercept = false;
                    }
                    break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }
    }
内部拦截,

重写子view的dispatchTouchEvent方法,设置父viewgroup的requestDisallowInterceptTouchEvent 的参数来做控制,
伪代码如下:

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                parent.requestDisallowInterceptTouchEvent(false);
                break;
            case MotionEvent.ACTION_MOVE:
                if(父类容器需要拦截)
                {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
                else
                {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                
                break;
        }
        boolean flag = super.dispatchTouchEvent(ev);
        return flag;
    }

相关文章

网友评论

    本文标题:android事件分发学习笔记

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