标签:

public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}提供 OnTouchListener
接口,让码农们在onTouch方法中来处理单一事件down、move和up(当然也可以重写onTouchEvent方法来处理),在onTouchEvent方法中将down、move和up组合成onClick
和 onLongClick 事件(相关的源码分析网上有很好的文章可以参考,这里就不详细写了)。并且onTouch方法优先于onTouchEvent方法被执行,onTouchEvent方法是否被执行又取决于onTouch方法的返回值,这是比较巧妙的,从事件发生的时间上来看,down事件刚发生时,是不可能触发onClick
和 onLongClick 的,move发生之后,也就不可能产生onLongClick了,而up发生后,才可能会有onClick。码农们可以让onTouch方法返回true,表示我只需要处理单一事件,不用再把down、move和up组合成onClick
和 onLongClick 。这种情况下,dispatchTouchEvent方法返回true,表示事件被响应了。如果onTouch方法返回false,才再去执行onTouchEvent方法,这种情况下dispatchTouchEvent方法的返回值就是onTouchEvent方法的返回值,只有onTouchEvent方法返回true才代表此次事件被响应了。<span style="font-family:Microsoft YaHei;font-size:14px;background-color: rgb(255, 255, 255);">public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// public void onUserInteraction(){}是一个空方法
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}</span>



<span style="font-family:Microsoft YaHei;font-size:14px;background-color: rgb(255, 255, 255);">public boolean dispatchTouchEvent(MotionEvent ev) {
// 这里是ACTION_DOWN的处理逻辑
if (action == MotionEvent.ACTION_DOWN) {
if (mMotionTarget != null) {
// 每次ACTION_DOWN时,都将mMotionTarget 设为null
// mMotionTarget 是一个比较重要的变量,它不为null则表示找到了响应事件的view对象
mMotionTarget = null;
}
// If we're disallowing intercept or if we're allowing and we didn't intercept
// 如果不允许拦截或者允许拦截但不拦截,则执行下边的逻辑
if (disallowIntercept || !onInterceptTouchEvent(ev)) {
// We know we want to dispatch the event down, find a child who can handle it, start with the front-most child.
// 将down事件分发下去,遍历,找到一个可以处理事件的子view
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = count - 1; i >= 0; i--) {
final View child = children[i];
// 子view必须要是VISIBLE的或者正在执行动画才可以响应事件
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
// 如果子view包含触摸点的坐标
if (frame.contains(scrolledXInt, scrolledYInt)) {
if (child.dispatchTouchEvent(ev)) {
// 调用子view的dispatchTouchEvent方法,如果返回true,则将child赋值给mMotionTarget
// 代表找到了一个响应事件的view对象,然后直接返回true
mMotionTarget = child;
return true;
}
// 如果执行到这里,说明ACTION_DOWN事件还没有被响应
}
}
}
}
}
final View target = mMotionTarget;
if (target == null) {
// target == null,意味着没有找到能响应事件的子view,则调用ViewGroup父类View的dispatchTouchEvent方法
return super.dispatchTouchEvent(ev);
}
// 无论 target 是否为 null ,ACTION_DOWN事件的处理都不能走到这里,在之下都是ACTION_MOVE和ACTION_UP的逻辑
// 如果执行到这里,说明有响应ACTION_DOWN事件的view对象,这就看我们是否被允许拦截和要不要拦截了
// 如果允许拦截并且拦截了ACTION_MOVE和ACTION_UP事件,则将ACTION_CANCEL事件分发给target
// 然后直接返回true,表示已经响应了该次事件
if (!disallowIntercept && onInterceptTouchEvent(ev)) {
ev.setAction(MotionEvent.ACTION_CANCEL);
if (!target.dispatchTouchEvent(ev)) {
// target didn't handle ACTION_CANCEL. not much we can do but they should have.
}
return true;
}
// 如果没有拦截ACTION_MOVE和ACTION_UP事件,则直接派发给target
return target.dispatchTouchEvent(ev);
}</span>标签:
原文地址:http://blog.csdn.net/h_w_g_t/article/details/51178447