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也同理
具体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方法处理。
总结