android点击事件的传递机制

版权声明:一起学习,一起进步 https://blog.csdn.net/qq_15623599/article/details/84582123

参考:https://blog.csdn.net/carson_ho/article/details/54136311#commentsedit ORZ拜读跪谢

1.1Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象,当一个点击事件(MotionEvent )产生后,系统需把这个事件传递给一个具体的 View 去处理。

事件类型                                            具体动作

MotionEvent.ACTION_DOWN  按下View(所有事件的开始)

MotionEvent.ACTION_UP          抬起View(与DOWN对应)

MotionEvent.ACTION_MOVE          滑动View

MotionEvent.ACTION_CANCEL        结束事件(非人为原因)

1.2事件分发的机制本质是将点击事件MotionEvent传递到某个具体的View以及处理的整个过程

1.3 事件在Activity、ViewGroup、View对象之间进行传递

1.4事件传递的顺序:Activity -> ViewGroup -> View`

1.5 事件分发过程由哪些方法协作完成?

    dispatchTouchEvent() 分发传递点击事件 当点击事件能够传递给当前View时会被调用。

    onInterceptTouchEvent() 判断是否拦截了某个事件 注意该方法只存在于ViewGroup 普通的view中没有该方法 在dispatchTouchEvent()内部调用  

    onTouchEvent()       处理点击事件 在dispatchTouchEvent()内部调用

------------------------------------------------------------------------------传递流程---------------------------------------------------------------------------------一:activity中的传递

点击屏幕,Activity的调用dispatchTouchEvent分发方法执行,该方法源码内实际有调用ViewGroup的dispatchTouchEvent分发方法。

此处实现了activity到viewGroup的传递。

如果ViewGroup的dispatchTouchEvent 返回true则事件不在传递,自己消费掉 即事件传递结束

如果ViewGroup的dispatchTouchEvent 返回false则事件传递,执行Activity.onTouchEvent()   无论该方法返回什么 都是结束事件传递。

上述 「源码内实际有调用ViewGroup的dispatchTouchEvent分发方法」实现了activity到viewGroup的传递

二:viewGroup中的传递

ViewGroup的dispatchTouchEvent分发方法中 源码内实际调用ViewGroup.onInterceptTouchEvent拦截方法 

如果ViewGroup的onInterceptTouchEvent返回true则表示拦截,不想子view传递点击事件,自己消费掉,调用自身的

onTouch()--->onTouchEvent()--->performClick()--->onClick() 即事件传递结束.

情景:自己重写拦截方法让它返回true或者没有view去接受该点击事件时。

如果ViewGroup的onInterceptTouchEvent返回false则事件传递,允许传递给子view,也就是for循环遍历子view中被点击的那个view,

如果没有相应子view(例如点击空白处) 则和返回true一样自己消费掉,不传递。

找到被电击的那个子view后执行子view的dispatchTouchEvent()分发事件方法,实现了GroupView到子view的传递

三:view中的传递

在view的dispatchTouchEvent()分发方法中源码中有调用view的onTouch()方法(这也是onTouch方法优先于onTouchEvent()方法和onClick()方法的原因)

button.setOnTouchListener(new OnTouchListener() {  
        @Override  
        public boolean onTouch(View v, MotionEvent event) {  
     
            return false; //则继续执行button的onClick()
            //return true;//则结束传递
        }  
    });

onTouch()方法可以重写定义。

onTouch方法若返回true则事件结束传递。

onTouch方法若返回false则会调用view的onTouchEvent()方法。

在onTouchEvent()中的抬起UP分支中

执行view的performClick方法--->view的onClick()方法返回true 结束传递。

至此到在子view的传递已经结束。

猜你喜欢

转载自blog.csdn.net/qq_15623599/article/details/84582123
今日推荐