dispatchTouchEvent(),该方法负责分发用户的触摸事件,而是否拦截该事件则由onInterceptTouchEent()决定,但最终的响应事件应该还是取决于onTouchEvent()。
触摸事件首先到达Activity的dispatchTouchEvent(), 然后对Activity的子控件进行遍历并依次调用它们的dispatchTouchEvent(),当子控件为ViewGroup时,重复这一过程,当子控件为View时,View的dispatchTouchEvent()会返回其OnTouchEvent()的执行结果,true表示消费了事件,当ViewGroup的所有子控件都返回false时,才会调用ViewGroup自身的onTouchEvent()(除非ViewGroup复写onInterceptTouchEvent()拦截了事件,这样事件将不会传递到子控件,而是直接到ViewGroup的OnTouchEvent())。
当在activity页面中添加MapView时,因为Activity重写了dispatchTouchEvent()做一些手势控制,为了使这部份手势控制在MapView上失效,所以在Activity的MotionEvent_UP事件中给dispatchTouchEvent()返回了true,结果导致MapView中的事件都只能响应到MotionEvent_MOVE,即缩放按键按下后不能弹起,无法拖拽地图,但是可以通过两个手指缩放之类……这些动作显然是MapView重写了onTouchEvent方法,如果在父控件就拦截MontionEvent的话便会导致MapView的手势控制出现问题
明白了原因就好改啦
在Activity的dispatchTouchEvent()中,当判断MotionEvent_UP的坐标点在MapView时,应该return父类调用super.dispatchTouchEvent(ev)让事件继续向下传递而非return true或false,这样才可以使MotionEvent_UP事件继续传递到MapView构成一次完整的触摸事件,又因为MapView已经消费了事件,所以也不用担心MapView会触发Activity的手势控制啦~。~
//在Activity的dispatchTouchEvent()中对MotionEvent.ACTION_UP事件做处理:
if (mCurrentFragment instanceof PathFragment){
PathFragment fragment = (PathFragment)mCurrentFragment;
if (fragment.isTouchMap(upY)){
return super.dispatchTouchEvent(ev);
}
}
if (offsetX < -50 && Math.abs(offsetY)<200){
nextFragment();
return true;//可以在此返回布尔值,则UP事件便不会在向下传递了,这样如果坐标在控件时也就不会触发其点击事件。
}else if (offsetX > 50 && Math.abs(offsetY)<200){
prevFragment();
return true;
}
//在fragment中创建判断事件坐标点是否在地图上的方法:
public boolean isTouchMap(float upY) {
int[] location = new int[2];
mapView.getLocationInWindow(location);
if (upY>location[1]){
//mapView.dispatchTouchEvent(ev);
return true;
}
return false;
}
总之,不要轻易给dispatchTouchEvent()返回boolean值,除非你不想传递事件或者只想传递不完整的触摸事件…
附: android onTouch()与onTouchEvent()的区别
1.onTouch方法:
onTouch方法是View的 OnTouchListener借口中定义的方法。
当一个View绑定了OnTouchLister后,当有touch事件触发时,就会调用onTouch方法。
(当把手放到View上后,onTouch方法被一遍一遍地被调用)
2.onTouchEvent方法:
onTouchEvent方法是override 的Activity的方法。
重新了Activity的onTouchEvent方法后,当屏幕有touch事件时,此方法就会别调用。
(当把手放到Activity上时,onTouchEvent方法就会一遍一遍地被调用)
3.touch事件的传递:
在一个Activity里面放一个TextView的实例tv,并且这个tv的属性设定为 fill_parent
在这种情况下,当手放到屏幕上的时候,首先会是tv响应touch事件,执行onTouch方法。
如果onTouch返回值为true,
表示这个touch事件被onTouch方法处理完毕,不会把touch事件再传递给Activity,
也就是说onTouchEvent方法不会被调用。
(当把手放到屏幕上后,onTouch方法被一遍一遍地被调用)
如果onTouch的返回值是false,
表示这个touch事件没有被tv完全处理,onTouch返回以后,touch事件被传递给Activity,
onTouchEvent方法被调用。
(当把手放到屏幕上后,onTouch方法调用一次后,onTouchEvent方法就会一遍一遍地被调用)