美文网首页
事件拦截整理

事件拦截整理

作者: 卡路fly | 来源:发表于2020-05-28 16:57 被阅读0次
    • 父类拦截DOWN事件后,所有事件无法传递给子类
    • onTouchListener先于onTouchEvent,onTouchListener返回true不会执行onTouchEvent
    • requestDisallowInterceptTouchEvent 子元素拦截父dispatch,父类intercept返回true也无效,down事件除外

    MotionEvent

    系统有一个线程在循环收集屏幕硬件信息,当用户触摸屏幕时,该线程会把从硬件设备收集到的信息封装成一个MotionEvent对象,然后把该对象存放到一个消息队列中。

    系统的另一个线程循环的读取消息队列中的MotionEvent,然后交给WMS去派发,WMS把该事件派发给当前处于活动的Activity,即处于活动栈最顶端的Activity。

    这就是一个先进先出的消费者和生产者的模板,一个线程不停的创建MotionEvent对象放入队列中,另一个线程不断的从队列中取出MotionEvent对象进行分发。

    当用户的手指从接触屏幕到离开屏幕,是一个完整的触摸事件,在该事件中,系统会不断收集事件信息封装成MotionEvent对象。收集的间隔时间取决于硬件设备,例如屏幕的灵敏度以及cpu的计算能力。目前的手机一般在20毫秒左右。

    MotionEvent事件

    ACTION_DOWN ——> 表示按下了屏幕,一个事件必然从ACTION_DOWN开始
    ACTION_MOVE ——> 表示移动手势
    ACTION_UP ——> 表示离开屏幕
    ACTION_CANCEL ——> 表示取消手势,一般由程序产生,不会由用户产生

    一个ACTION_DOWN, n个ACTION_MOVE,1个ACTION_UP,就构成了Android中众多的事件。

    Android中的事件onClick, onScroll, onFling等等,都是由许多个Touch组成的。

    一个原则,所有的touch事件都是从父容器开始向下传递的,呈U字形。

    MotionEvent中的坐标:

    • getRawX:触摸点相对于屏幕的坐标
    • getX: 触摸点相对于按钮的坐标
    • getTop: 按钮左上角相对于父view(LinerLayout)的y坐标
    • getLeft: 按钮左上角相对于父view(LinerLayout)的x坐标

    OnTouchListener & onTouch

        public boolean dispatchTouchEvent(MotionEvent event) {//返回true,表示该View内部消化掉了所有事件。返回false,表示View内部只处理了ACTION_DOWN事件,事件继续传递,向上级View(ViewGroup)传递。
        ...
                if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                        && li.mOnTouchListener.onTouch(this, event)) {//此处的onTouch方式就是回调的我们注册OnTouchListener时重写的onTouch()方法
                    return true;
                }
            
                if (onTouchEvent(event)) {// onTouchEvent参考下面源码
                    return true;
                }
            ...
        }
    

    OnTouchListener不为null(即给view注册了OnTouchListener)——> 重写的onTouch()方法中返回false ——> 执行onTouchEvent方法 ——> 当前控件是ENABLED状态——> onClick()回调方法执行

    OnTouchListener不为null ——> 重写的onTouch()方法返回true ——> onTouchEvent方法不执行 ——> onClick()回调方法不会执行

    OnTouchListener为null ——> 执行onTouchEvent方法 ——> 当前控件是ENABLED状态——> onClick()回调方法执行

    OnTouchListener为null ——> 执行onTouchEvent方法 ——> 当前控件不是ENABLED状态——> onClick()回调方法不会执行


    整理自:https://blog.csdn.net/wuseyukui/article/details/46523899

    相关文章

      网友评论

          本文标题:事件拦截整理

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