1.触摸消息是消息获取模块直接派发给应用程序的.不需要有按键消息先派发个Wms处理
2.触摸消息在处理时,需要根据坐标计算先派发给那个View|ViewGroup
3.应用程序可以完全控制触摸行为
4.子视图优先于父视图处理消息.既首先子视图获取消息,子视图不处理时交给父视图处理.
1.总体派发过程
同样,由消息处理模块将消息通过ViewRoot的ViewRootHandler传递给ViewRoot,最后由deliverInputEvent处理.
1.物理像素到逻辑像素的转换.触摸消息对应物理屏幕,需要转换到系统逻辑坐标
2.如果说Down消息,调用ensureTouchMode 进入触摸模式,否则进入按键模式
3.将屏幕坐标转换到视图坐标.触摸消息本身坐标是相对于屏幕左上角.而视图可以认为是没有边界的.他内部处理消息时所需要的左边是相对于视图本身的.
4.调用mView.dispatchTouchEvent将消息派发给根视图,该函数内部继而将消息派发给整个view树.根视图可以是DecorView或者ViewGroup
5.如果以上视图都没有消耗消息,最后处理屏幕边界偏移.他的作用是用户触摸屏幕边界时,系统自动对原始消息进行偏移,然后早新偏移后的位置上寻找匹配的视图.
2.根视图内部派发过程
1.mView.diapathchTouchEvent过程,mView可能是ViewGroup或DecorView
2.DevorView中,会判断Callback是否存在,Callback既activity,存在就调用activity的dispatchTouchEvent,否则调用ViewGroup的dispatchTouchEvent
3.activity的dispatchTouchEvent调用如下
3.1如果是down消息.调用onUserInteraction,在消息处理前做点什么
3.2 调用getWindow().superDispatchTouchEvent 将消息又派发给DecorView,最后调用ViewGroup的dispatchTouchEvent
3.3 如果DecorView没有消耗消息,就回调自己的onTouchEvent,默认什么也不做.
所以,最后都是走到了viewgroup的dispatchTouchEvent
4.viewgroup的内部消息派发过程
4.1将viewgroup的布局坐标转换为视图坐标,布局坐标就是父视图给子视图分配的布局大小.视图坐标是视图内容的实际大小,
试图坐标不受物理屏幕大小限制.这种转化用来viewgroup判断触摸点落在了那个子view中,子view的坐标都是相对于该viewgroup的试图坐标.
4.2处理down消息,判断触摸点落到那个子视图中.
4.2.1先判断该viewGroup是否被禁止获取touch信息,如果没有.就回调onInterceptTouchEvent判断是否需要拦截事件.如果不拦截就继续向子view分发.
4.2.2寻找子视图newTouchTarget .看那个子视图的坐标点包括触摸点.
4.3 找到newTouchTarget后,判断该子视图是否是,如果是ViewGrogup,就递归调用ViewGrogup.dispatchTouchEvent().如果不是意味着递归调用结束.
4.4如果是UP或者CANCEL,就清除掉FLAG_DISALLOW_INTERCEPT,以为着下次按下时ViewGroup还会重新拦截消息.
4.5判断newTouchTarget是否为空,空代表所有子窗口没有消耗该消息,所以ViewGroup本身需要处理该消息.
不为空就递归调用newTouchTarget,newTouchTarget是链表结构.递归调用他的view来处理消息.到此事件分发在ViewGroup中结束.
5.此时触摸事件会交给View.dispatchTouchEvent来处理.view可能是上一步ViewGroup的子视图,或者是ViewGroup自己.该方法在View内部.和ViewGroup方法同名.
5.1 调用 onFilterTouchEventForSecurity处理窗口出于模糊状态下的消息.
5.2 回调视图监听者的onTouch方法,如果该方法处理了消息,则直接返回
5.3 调用 onTouchEvent ,程序可以重载该方法,该方法有默认的执行逻辑
5.3.1 判断视图是否是disabled状态,如果是,直接返回true,既消耗消息
5.3.2 处理消息代理mTouchDelegate.onTouchEvent(event),代理是为了扩大view的触摸区域,代理先处理消息,处理后view不再处理,
代理没处理则需要view自己处理.源码没有实现该功能
5.3.3 判断view是否可点击,如果不可点击直接返回.如果可点击.分别对down,move,up,cancel进行处理
5.3.4 Activity_down消息中,启动tap检测.发送一个异步延迟消息.
5.3.5 Activity_move消息,判断是否移动到视图外边,如果是,移除tap监测和longPress监测,
5.3.6 Activity_up 消息.判断up消息的时间段,决定发生tap还是press还是longpress,移除不到时间的异步延迟消息.
根据focusTaken变量判断是否发成click事件.
至此.触摸的派发过程结束.
网友评论