重写Activity的dispatchTouchEvent与百度地图MapView事件冲突

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方法就会一遍一遍地被调用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值