标签:
dispatchTouchEvent 分发事件
return false; //表示分发,默认false;
return true; // 表示不分发;
onInterceptTouchEvent 拦截事件
当dispatchTouchEvent 确认分发,会启动拦截事件;
return false; //表示不拦截,默认false;
return true; // 表示拦截;
注意:拦截是相当于它的孩子(也就是说不会拦截自己,如果拦截,则TouchEvent会传到他自己,而它孩子就接收不)
不拦截会继续往他的孩子递归是否onInterceptTouchEvent ;
onTouchEvent 触摸事件
return false; //表示不消费,默认false;
return true; // 表示消费;
当onInterceptTouchEvent 确认拦截,会问自己是否要消费TouchEvent,
如果拦截了又不消费则,Touch结束;
invalidate():让整个view失效,这样view会被重新调用, 配合onDraw()使用;
事件的分发原理图:
图1:
图二:
案列: 分发的例子
下面红色框区域的结构是ScrollView, 它的孩子是一些TextView;
分析:
1.当点击它任意一个孩子(TextView)时,如果ScrollView不进行onInterceptTouchEvent ,则它就不可以在菜单上进行左右滑动;
2.但是如果拦截了全部,则它的孩子又会消费不了TouchEvent;
解决方法:
只有左右移动的时候进行拦截,这样父亲就拥有了TouchEvent,可在菜单上继续左右滑动,
而上下移动或静止的时候就不拦截,这样孩子又有了TouchEvent,那么孩子就可以点击了;
实例代码:
/**
* 当滑动的时候,需要拦截TouchEvent时间,让scrollView消化,否则会分发到孩子去;
* 当不滑动的停止的时候,不拦截,则会分发到孩子去,也就是TexView;
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
// 只有水平滑动时才拦截touch
case MotionEvent.ACTION_DOWN:
startX = (int) (ev.getRawX() + 0.5f);
startY = (int) (ev.getRawY() + 0.5f);
break;
case MotionEvent.ACTION_MOVE:
int newX = (int) (ev.getRawX() + 0.5f);
int newY = (int) (ev.getRawY() + 0.5f);
int dx = Math.abs(startX - newX);
int dy = Math.abs(startY - newY);
if (dx > dy) {
// 水平滑动,只有水平滑动才会dx.dy
return true;
}
startX = (int) ev.getRawX();// 初始化当前位置
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
TouchEvent的传递机制
标签:
原文地址:http://www.cnblogs.com/relice/p/4858582.html