8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
View与ViewGroupView与事件相关的方法有onTouchEvent()、dispatchTouchEvent()
ViewGroup与事件相关的方法有onTouchEvent()、onEvent()、onInterceptTouchEvent
Activity可以当做ViewGroup来处理。
ViewGroup是View的子类,ViewGroup重写了View中的dispatchTouchEvent(),并添加了onInterceptTouchEvent()
1.事件分发过程
Touch事件发生时,事件从顶层ViewGroup,调用ViewGroup的、dispatchTouchEvent()进行事件分发,事件分发到子View或子ViewGroup。
ViewGroup执行事件分发的过程实际上就是逐个调用其子View/ViewGroup中的dispatchTouchEvent(),调用过程的伪代码:1
2
3
4
5
6
7
8
9
10public boolean (MotionEvent e){
....
View[] views = getChildViews();
for(View v in views){
if(v.dispatchTouchEvent(e)){
return true
}
}
....
}
子ViewGroup收到事件,会继续调用自己的dispatchTouchEvent()将该事件进一步向下分发;子View收到事件,会调用自己的dispatchTouchEvent()将事件分发给自己,在子View的dispatchTouchEvent()方法中实际上又调用了onTouchEvent(),简化版代码如下:1
2
3
4public boolean (MotionEvent e){
...
return this.onTouchEvent()
}
因此默认情况下,dispatchTouchEvent的返回值与onTouchEvent一致。
2.对象捕获过程事件从顶层分发到底层,该过程是为了宣召执行事件的响应的目标。
Android屏幕事件从ACTION_DOWN开始,之后会触发ACTION_MOVE和ACTION_UP等事件。
当屏幕事件触发时,首先发出ACTION_DOWN事件进行探测,寻找后续事件执行的目标,即如果某个子View的onTouchEvent返回true,则表示该View消耗该事件,后续事件执行的目标就确定为该View。该过程调用流程为:ViewGroup执行dispatchTouchEvent -> 子View执行dispatchTouchEvent -> 子View执行nTouchEvent。事件响应目标确定后,后续ACTION_MOVE等事件会直接在该目标上执行。当没有找到目标时,事件交给ViewGroup处理,ViewGroup调用它自身的onTouchEvent进行处理(实际上是ViewGroup调用父类View的方法super.dispatchTouchEvent(),View中的dispatchTouchEvent()调用onTouchEvent,而刚好ViewGroup覆写了该方法)。
ViewGroup还有一个onInterceptTouchEvent() 方法,表示事件拦截。当该方法返回true时,事件被拦截在ViewGroup层,无法继续分发到子View,此时事件的处理就会在ViewGroup中处理。
以上的过程,类似于打仗中的情景。两军交战,首先派侦察兵去敌方阵营侦察目标,找到目标后,发回成功信号,则任务就会在该目标处执行,如果发生了意外,侦察兵被拦截了,则任务会在本方阵营执行。军官通过dispatchTouchEvent()方法命令侦察兵去执行任务(这里ACTION_DOWN事件就扮演了侦察兵的角色),发回的成功信号即子View的onTouchEvent返回了true,如果onInterceptTouchEvent()返回true,则表示发生了意外,后续任务只能在本方阵营执行(ViewGroup调用onTouchEvent处理事件)。
整个过程伪代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26View mTarget = null ;
public boolean (MotionEvent e){
if(e.getEventType == ACTION_DOWN){
mTarget = null ;
if (!onInterceptTouchEvent()) {
View[] views = getChildViews();
for(View v in views){
if(v.dispatchTouchEvent(e)){
return true
}
}
}
}
if (mTarget == null) {
return super.dispatchTouchEvent(e) ; // 实际上最终调用了this.onTouchEvent()
}
// 拦截事件的处理方式
if(onInterceptTouchEvent()){
}
// 此处mTarget 不为空,表示目标确定,后续事件直接处理
return mTarget.dispatchTouchEvent()
}
另外,ViewGroup的dispatchTouchEvent实际上做了两件事:事件分发(调用子View的方法)和事件处理(调用自己的onTouchEvent),
View的dispatchTouchEvent只是简单的将事件发给自己,并调用了onTouchEvent返回处理结果。