三、Behavior拦截机制
右滑删除view的实现(SwipeDismissBehavior),是通过重写Behavior的下面的方法实现:
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
switch (MotionEventCompat.getActionMasked(event)) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Reset the ignore flag
if (mIgnoreEvents) {
mIgnoreEvents = false;
return false;
}
break;
default:
mIgnoreEvents = !parent.isPointInChildBounds(child,
(int) event.getX(), (int) event.getY());
break;
}
if (mIgnoreEvents) {
return false;
}
ensureViewDragHelper(parent);
return mViewDragHelper.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (mViewDragHelper != null) {
mViewDragHelper.processTouchEvent(event);
return true;
}
return false;
}
前面说过Behavior相当于一个代理,那Behavior如何实现代理功能的呢?
CoordinatorLayout.onInterceptTouchEvent
CoordinatorLayout.onTouchEvent
CoordinatorLayout.performIntercept
MyBehavior.onInterceptTouchEvent
MyBehavior.onTouchEvent
在Col中onInterceptTouchEvent和onTouchEvent方法中调用performIntercept方法看子view的Behavoir是否拦截:
private boolean performIntercept(MotionEvent ev, final int type) {
...
for (int i = 0; i < childCount; i++) {
final View child = topmostChildList.get(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final Behavior b = lp.getBehavior();
...
if (!intercepted && b != null) {
switch (type) {
case TYPE_ON_INTERCEPT:
intercepted = b.onInterceptTouchEvent(this, child, ev);
break;
case TYPE_ON_TOUCH:
intercepted = b.onTouchEvent(this, child, ev);
break;
}
if (intercepted) {
mBehaviorTouchView = child;
}
}
...
return intercepted;
}
在这个方法中会循环遍历所有的子view,看看谁的代理Behavior要拦截事件。
参考资料
- 官网: https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html
- Behavior的实现原理:http://www.myexception.cn/mobile/2052223.html
- 嵌套滑动机制:http://blog.csdn.net/wuyuxing24/article/details/51112645
- Behavior的拦截一切的机制:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0224/3991.html