自定义View时requestDisallowIntercept
坑
在处理自定义View有事会使用requestDisallowInterceptTouchEvent(true)
来屏蔽父类中的onInterceptTouchEvent()
方法。但发现调用之后有时不起作用。查看源码,确实requestDisallowInterceptTouchEvent()
方法设置的mGroupFlags
标志位是用来控制onInterceptTouchEvent()
方法的调用。
ViewGroup中dispatchTouchEvent部分源码
// Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// There are no touch targets and this action is not an initial down
// so this view group continues to intercept touches.
intercepted = true;
}
填
问题就出在了resetTouchState()
这步上。
/**
* Resets all touch state in preparation for a new cycle.
*/
private void resetTouchState() {
clearTouchTargets();
resetCancelNextUpFlag(this);
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
mNestedScrollAxes = SCROLL_AXIS_NONE;
}
虽然我们设置了requestDisallowInterceptTouchEvent(true)
,但每次dispatchTouchEvent()
调用时都会重置mGroupFlags
标志位,所以在判断disallowIntercept
是只要是ACTION_DOWN
事件时永远是false
。所以ACTION_DOWN
被拦截了基本没戏了,其他事件只能从mFirstTouchTarget != null
上下手了。mFirstTouchTarget
是在intercepted
为false
时赋值的。所以让onInterceptTouchEvent()
在ACTION_DOWN
事件是返回false即可。所以可以集成该类,复写其onInterceptTouchEvent()
方法。
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
return false;
break;
default:
return super.onInterceptTouchEvent(ev);
break;
}
}
这样在其子类的onTouchEvent()
方法中调用getParent().requestDisallowInterceptTouchEvent(true);
就可以生效了。
参考博客
http://blog.csdn.net/jiwangkailai02/article/details/46666147
http://blog.csdn.net/u014623470/article/details/51658609