事件传递 android,Android事件传递

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前言

最近在实现自定义Sticklayout,发现有时候move子view时不能整体滑动,log日志如下:1

2

3

4

5

6

7

8

9

1007-16 20:48:50.945 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_down

linearlaout onInterceptTouchEvent:action_down

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlaout onInterceptTouchEvent::false

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_down

customview onTouchEvent:action_down

customview onTouchEvent::false

customview dispatchTouchEvent::false

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent:action_down

linearlayout onTouchEvent::false

linearlayout dispatchTouchEvent::false

可以发现,只响应了ACTION_DOWN,就是没有调用后续的ACTION_MOVE,ACTION_UP,跳回到viewGroup的onTouchEvent后事件就被掐掉了,为什么呢。

经过查阅资料得知,发现只需将子view设置为clickable=true即可

但其中原理究竟是怎样的

具体分析

这里先给出结论事件传递Activity-ViewGroup-view,如下图所示。

事件传递的最小单位是view的onTouchEvent,从onTouchEvent开始开始冒泡(如果布局有嵌套会递归弹栈)依次回传ViewGroup的onTouchEvent(如果onTouchEvent()没有返回true)

View 如果不是clickable ,longClickable,contextClickable (可点击状态),不会消费事件

如果给View设置了TouchListener也能处理后续事件,在ACTION_DWON 时返回 true

ViewGroup也是继承于View,ViewGorup本身clickable=false

给View设置clickListener 同时会让 clickable = true

如果View 没有消费ACTION_DOWN 事件,之后其他的ACTION_MOVE,ACTION_UP等事件也不会被响应,(包括上层的ViewGroup),ViewGroup 继承于View,所以ViewGroup也同理d018b1c66c6845ca10a5cfab9a8a0474.png

具体viewGruop,子view的dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent的调用关系是怎样的,LOG分析如下:

子View不消耗事件的情况

即是最开始的情况,子View不消费任何事件,返回到viewGroup的onTouchEvent

但如果View 没有消费ACTION_DOWN 事件,之后其他的ACTION_MOVE,ACTION_UP等事件也不会被响应1

2

3

4

5

6

7

8

9

1007-16 20:48:50.945 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_down

linearlaout onInterceptTouchEvent:action_down

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlaout onInterceptTouchEvent::false

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_down

customview onTouchEvent:action_down

customview onTouchEvent::false

customview dispatchTouchEvent::false

07-16 20:48:50.946 16256-16256/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent:action_down

linearlayout onTouchEvent::false

linearlayout dispatchTouchEvent::false

子View消费事件的情况

调用顺序如下:

当子view消费了事件,子View的onTouchEvent返回true,这样返回ViewGroup就在dispatchTouchEvent结束了,不会继续调用ViewGroup的onTouchEvent1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

2907-16 20:59:52.919 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_down

07-16 20:59:52.920 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlaout onInterceptTouchEvent:action_down

linearlaout onInterceptTouchEvent::false

07-16 20:59:52.920 17114-17114/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_down

07-16 20:59:52.921 17114-17114/com.zhangjie.androidtouch E/tiaoshi: customview onTouchEvent:action_down

customview onTouchEvent::true

customview dispatchTouchEvent::true

07-16 20:59:52.921 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent::true

//ACTION_MOVE

07-16 21:02:17.082 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_move

linearlaout onInterceptTouchEvent:action_move

linearlaout onInterceptTouchEvent::false

07-16 21:02:17.082 17114-17114/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_move

customview onTouchEvent:action_move

07-16 21:02:17.083 17114-17114/com.zhangjie.androidtouch E/tiaoshi: customview onTouchEvent::true

customview dispatchTouchEvent::true

07-16 21:02:17.083 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent::true

//ACTION_UP

07-16 20:59:52.923 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_up

linearlaout onInterceptTouchEvent:action_up

linearlaout onInterceptTouchEvent::false

07-16 20:59:52.923 17114-17114/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_up

customview onTouchEvent:action_up

customview onTouchEvent::true

customview dispatchTouchEvent::true

07-16 20:59:52.923 17114-17114/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent::true

当onInterceptTouchEvent拦截了事件的时候

当onInterceptTouchEvent在ACTION_MOVE的时候拦截事件时,则会有另一番表现

拦截代码1

2

3

4

5

6

7

8

9

10

11public boolean (MotionEvent ev){

// log(ev,ON_INTERCEPT_TOUCH_EVENT);

switch (ev.getAction()){

case MotionEvent.ACTION_MOVE:

return true;

}

boolean result = super.onInterceptTouchEvent(ev);

Log.i(TAG,ON_INTERCEPT_TOUCH_EVENT+":"+result);

return result;

}

log如下1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

2507-16 21:08:39.683 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_down

linearlaout onInterceptTouchEvent:action_down

07-16 21:08:39.684 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlaout onInterceptTouchEvent::false

07-16 21:08:39.684 18219-18219/com.zhangjie.androidtouch E/tiaoshi: customview dispatchTouchEvent:action_down

customview onTouchEvent:action_down

07-16 21:08:39.685 18219-18219/com.zhangjie.androidtouch E/tiaoshi: customview onTouchEvent::true

customview dispatchTouchEvent::true

07-16 21:08:39.685 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent::true

07-16 21:08:39.701 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_move

linearlaout onInterceptTouchEvent:action_move

07-16 21:08:39.701 18219-18219/com.zhangjie.androidtouch E/tiaoshi: customview onTouchEvent::true

customview dispatchTouchEvent::true

07-16 21:08:39.701 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent::true

07-16 21:08:39.717 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_move

linearlayout onTouchEvent:action_move

07-16 21:08:39.718 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent::false

linearlayout dispatchTouchEvent::false

07-16 21:08:39.733 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout dispatchTouchEvent:action_move

07-16 21:08:39.733 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent:action_move

07-16 21:08:39.734 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent::false

linearlayout dispatchTouchEvent::false

linearlayout dispatchTouchEvent:action_up

linearlayout onTouchEvent:action_up

07-16 21:08:39.878 18219-18219/com.zhangjie.androidtouch I/tiaoshi: linearlayout onTouchEvent::false

linearlayout dispatchTouchEvent::false

可以发现,当onInterceptTouchEvent返回true,拦截了事件后,事件就被viewGroup处理了,不再传到子view中

事件分发:public boolean dispatchTouchEvent(MotionEvent ev)

Android事件以隧道方式逐层向下传递。事件首先由dispatchTouchEvent方法分发,分发逻辑如下:

return true;由该dispatchTouchEvent方法消费并且停止分发。

return false;返回给父view的onTouch方法处理

return super.dispatchTouchEvent(ev);有当前view的onInterceptTouchEvent()拦截处理。

事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)

当前view拦截到事件后,处理流程如下:

return false;表示放行由当前view的子view的dispatchTouchEvent分发处理。

return true或return super.onInterceptTouchEvent()表示拦截该事件,由该View的Ontouch方法处理。

事件响应:public boolean onTouchEvent(MotionEvent ev)

return true表示消费。

return false或return super.onTouch()则此事件传递给上层View的onTouch方法处理。

总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值