一、哪些地方有事件?
Activity、ViewGroup、View、Key按键
二、常用事件有哪些?
ACTION_DOWN:手指接触到屏幕的那一瞬间触发
ACTION_MOVE:手指在屏幕上接触滑动时触发,且是多次触发
ACTION_UP:手指抬起离开屏幕的那一瞬间触发
ACTION_CANCEL:事件被上层拦截时触发
三、重点方法有哪些?
Activity ViewGroup View
dispatchTouchEvent √ √ √
onTouchEvent √ √ √
onInterceptTouchEvent × √ ×
dispatchTransformedTouchEvent × √ ×
四、如何传递(重点)?
我们在写自定义view解决事件冲突的时候,往往是要控制事件流的走向,那事件到底是怎样传递和分发的呢?

我先说明一下,你直接想象成ACTION_DOWN事件。首先,你手指点在屏幕上的那一刹那,事件就产生和传递了。事件首先会交给Activity,然后Activity的布局本质是一个树形结构,又称为View树。至于这个View树的设计模式的精髓,咱们不在本篇幅讨论。Activity首先会传递给树的根节点,一般为一个ViewGroup。如果为View,那就简单了。什么情况下Activity会交给根布局呢?最先被调用的是Activity的
dispatchTouchEvent,return super.dispatchTouchEvent才会交给根布局,return true或false都会丢掉事件。现在事件来到了最外层的ViewGroup的dispatchTouchEvent,这个哥们有个经纪人,onInterceptTouchEvent,事件每次往子控件传,都会问这个哥们,如果onInterceptTouchEvnet return了
true,就会把事件拦截下来,并且不会继续往子控件传了。而是交给自己的执行总监onTouchEvent去处理事件,onTouchEvent会返回一个结果给自己,如果为true,那么事件彻底玩完,也就是通常大家所说的被消耗了。如果为false,就会向外层父容器传递,最后会调Activity的onTouchEvent,然后事件流失掉,事件走到了它的“人生尽头”。事件是怎么传递给子控件的呢?那就是在dispatchTouchEvent中调了
dispatchTransformedTouchEvent。
上系统源码:
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
transformedEvent.offsetLocation(offsetX, offsetY);
if (! child.hasIdentityMatrix()) {
transformedEvent.transform(child.getInverseMatrix());
}
handled = child.dispatchTouchEvent(transformedEvent);
}
有子控件的情况下,dispatchTransformedTouchEvent就会顺利把事件交给子控件的dispatchTouchEvent。最后补充一点,系统默认的事件走向是由Activity、ViewGroup、
View依次触发onTouchEvent,每一级都触发。
以上仅仅为事件传递机制的基础,我们仅仅讨论了DOWN这一分支,至于什么情况下会触发onClick?
什么情况下会触发onTouch?onTouch和onTouchEvent有什么区别?我们以后有机会再讨论。
网友评论