Android中touch事件机制学习总结
Android里View一般是ImageView、textView、Button等继承于View的控件。LinearLayout等的五大布局控件,都是继承自ViewGroup,而ViewGroup本身是继承自View。
Android中各类事件均由多个Touch事件构成的(一个ACTION_DOWN, n个ACTION_MOVE,1个ACTION_UP)
Android事件机制总是经由先分发dispatch,(从根View依次传递到子View),再进行事件消费处理(从最里面事件消费View依次向外层传递)的形式实现。
MotionEvent事件类型分为如下几种:
ACTION_DOWN:手指按下屏幕的瞬间ACTION_MOVE:手指在屏幕上移动
ACTION_UP:手指离开屏幕瞬间
ACTION_CANCEL :取消手势,一般由程序产生,不会由用户产生
图片来自网络:
0、dispatchTouchEvent主要用来分发事件,函数主要作用是来决定当前的事件是交由自己消费处理,还是交由子控件处理。
1、onInterceptTouchEvent(只有ViewGroup才有该回调接口)用来定义是否截取touch事件,若想截获必须覆盖ViewGroup中该方法。
2、事件消息在整个dispatchTouchEvent过程中,若子view.dispatchTouchEvent返回true,父view中将不再处理该消息,但前提是该消息没有被父view截取,在整个touch消息处理过程中,若处理函数返回true,我们称之为消费了该touch事件,并且后面的父view将不再处理该消息。
3、在整个touch事件过程中,从Action_Down到Action_Up,若父ViewGroup的函数onInterceptTouchEvent一旦返回true,消息将不再派发给子view,细分可为两种情况,若是在Action_down时onInterceptTouchEvent返回true,不会派发任何消息给子view,并且后面onInterceptTouchEvent函数将不再会被执行,若是Action_down时onInterceptTouchEvent返回false ,而后面touch过程中onInterceptTouchEvent为true,父viewGroup会把Action_Cancel派发给子view,也之后不再派发消息给子view,并且onInterceptTouchEvent函数后面将不再被执行。
4、如果消费了Action_Down事件,找到target子view消费事件,则后续其他事件如Action_Move等都会直接给该子view处理消费。前提是Action_Down后没有被父ViewGroup的函数onInterceptTouchEvent拦截。
5、一旦找不到消费事件的子view,target为null,会调用父类View类的dispatchTouchEvent,进行事件处理(注意区别于ViewGroup重写的dispatchTouchEvent)
6、View类的dispatchTouchEvent处理比较简单,就是先进行执行mOnTouchListener.onTouch,false则执行onTouchEvent,里面Up事件时判断有没有onClick事件。
分析View的事件处理:
0、View.dispatchTouchEvent->View.setOnTouchListener(处理onTouch)->View.onTouchEvent->View.onClick
1、onTouch的组件必须是可点击的比如Button,ImageButton等等,此处CLICKABLE为true,才会进入if方法,最后返回true。如果是ImageView、TexitView这些默认为不可点击的View,此处CLICKABLE为false,最后返回false。当然会有特殊情况,如果给这些View设置了onClick监听器,此处CLICKABLE也将为true。
2、onTouch()方法中返回false —> 执行onTouchEvent方法 —> 导致onClick()回调方法执行。返回true —> onTouchEvent方法不执行 —> 导致onClick()回调方法不会执行
3、onTouchEvent方法如果返回true,表示onTouchEvent处理消费了事件,此时事件终结;如果fasle,则表示不响应事件,那么该事件将会不断向上层View的onTouchEvent方法传递,直到某个View的onTouchEvent方法返回true,如果到了最顶层View还是返回false,那么认为该事件不消耗,则在同一个事件系列中,当前View无法再次接收到事件,该事件会交由Activity的onTouchEvent进行处理