扩展事件分发机制 dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent,并实现了requestDisallowInterceptTouchEvent方法。
注意
- 如果根布局或者中间的ComponentContainer实现的是View而非ViewGroup,那么事件将不会继续往下传递。
- 视图树中间可以出现断层,即出现未实现View或ViewGroup的控件,事件会跳过并往下传递。
- 未实现View或ViewGroup的控件,如果设置了setTouchEventListener,那么事件将在回调返回true后直接被消费,而导致不会被分发。
- 如果遇到super.onTouchEvent或者super.onInterceptTouchEvent,需要去父类查看逻辑并移植进来,如果是普通的布局或者控件一般是可以忽略,或者返回false的。
- 如果遇到super.dispatchTouchEvent则可以直接使用ViewGroupHelper/ViewHelper的dispatchTouchEvent来替代。
- 暂时只支持单点触摸的分发
使用
ComponentContainer
- ComponentContainer需要实现Component.TouchEventListener以及ViewGroup接口
- 设置setTouchEventListener
- 在ohos的onTouchEvent内调用DispatchHelper的dispatch方法
- 转发ViewGroup接口内的dispatchTouchEvent、isConsumed、requestDisallowInterceptTouchEvent方法至ViewGroupHelper实现,并在onInterceptTouchEvent、onTouchEvent内实现具体分发逻辑
Component
- Component需要实现Component.TouchEventListener以及View接口
- 设置setTouchEventListener
- 在ohos的onTouchEvent内调用DispatchHelper的dispatch方法
4、转发ViewGroup接口内的dispatchTouchEvent、isConsumed方法至ViewHelper实现,并在onTouchEvent内实现具体分发逻辑
requestDisallowInterceptTouchEvent
Component需要父控件不拦截事件,可以调用DispatchHelper的requestDisallowInterceptTouchEvent方法
接着打印每个函数的日志,并且尝试修改父控件的onInterceptTouchEvent、onTouchEvent,以及子控件的onTouchEvent的值,并查看日志结果。
也可以再多尝试几层ViewGroup实现,来实现更复杂的效果。
实现
由于ohos的事件传递是冒泡形式,即事件会先到目标控件内,如果目标控件不消耗事件,则冒泡到父控件内。而安卓的事件则是先传递到父控件,再经过分发,传递到目标控件内。
因此DispatchHelper的主要作用就是查找视图树内所有实现了View或ViewGroup的控件,并调用顶层控件的dispatchTouchEvent函数向下分发事件。并过滤掉由于事件冒泡,而传递过来的重复事件。
ViewHelper、ViewGroupHelper则主要实现了安卓的View、ViewGroup中dispatchTouchEvent函数的逻辑。