这是学习《android开发艺术探究》的笔记 如果有什么不对的地方,欢迎指出。
1.验证P143第五点
如果View不消耗ACTION_DOWN以外的其他事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,并且当前View可以持续收到后续的事件 ,最终这些消失的点击事件会传递给Activity
情景 1. onInterceptTouchEvent始终拦截事件,onTouchEvent消耗ACTION_DOWN事件,不消耗其他事件
public class MyViewGroup extends FrameLayout {
private static final String TAG = "MyViewGroup";
public MyViewGroup(@NonNull Context context) {
super(context);
}
public MyViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyViewGroup(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
String ActionStr = Util.getActionStr(action);
boolean consume;
consume = true;
Log.i(TAG, "onInterceptTouchEvent"+(consume?"拦截":"不拦截") + ActionStr);
return consume;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
String ActionStr = Util.getActionStr(action);
boolean consume;
if (action == MotionEvent.ACTION_DOWN) {
consume = true;
} else {
consume = false;
}
Log.i(TAG, "dispatchTouchEvent"+(consume?"消耗":"不消耗") + ActionStr);
return consume;
}
}
结果:当前View可以持续收到后续的事件
onInterceptTouchEvent拦截ACTION_DOW
onTouchEventt消耗ACTION_DOWN
onTouchEvent不消耗ACTION_MOVE
onTouchEvent不消耗ACTION_MOVE
onTouchEvent不消耗ACTION_UP
2.源码分析
if (!canceled && !intercepted) {
for(遍历child){
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
newTouchTarget = addTouchTarget(child, idBitsToAssign);
break;
}
}
}ß
if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
}
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handled = child.dispatchTouchEvent(event);
}
}
2.1源码逻辑
因为child消耗了ACTION_DOWN事件,
所以
- dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)返回true,
- addTouchTarget将被调用导致mFirstTouchTarget!=null
- dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER,IDS)不会被调用,即"父元素的onTouchEvent并不会被调用"。
而且child会在viewGroup不拦截事件的前提下,持续受到事件
所以书中会说
(4)如果View不消耗ACTION_DOWN以外的其他事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,并且当前View可以持续收到后续的事件











网友评论