事件机制 android,Android事件机制简述

66b52468c121889b900d4956032f1009.png

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返回处理结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值