ScrollView 嵌套地图控件 产生滑动冲突的问题

使用高德地图控件嵌套在ScrollView下面会产生滑动冲突的问题,使得地图的滑动,缩放变得不流畅,卡顿
借此也温习一下事件分发过程

所以在地图滑动事件的时候要屏蔽掉ScrollView的拦截事件
在MapView 的外层套一层自定义容器,解决这个滑动冲突,代码如下:
相关说明放在注释中

/*
* 地图容器,,解决ScrollView  嵌套MapView 滑动冲突的问题
*
* */
public class MapContainer extends RelativeLayout {

    public MapContainer(Context context) {
        super(context);
    }
    public MapContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //我们现在需要在手指抬起的时候交由父布局拦截我子View的事件,也就是交由ScrollView滑动处理
//       requestDisallInterceptRouchEvent(true);
        // 但是在按下或者移动的时候禁用父布局的拦截事件,也就是
//        requestDisallInterceptRouchEvent(true);这时候地图滑动就正常了
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            requestDisallowInterceptTouchEvent(false);
        } else {
            requestDisallowInterceptTouchEvent(true);
        }
        //返回false触摸事件才会传递到子View中,否则永远不会得到分发
        return false;
    }
    
    /*
    * retuan true 是需要当前的View处理这次的touch事件,以后发出的ACTION_MOVE,ACTION_UP还是要接收,
    * 而且这次的action已经被这个View给消费掉了,父布局层的ViewGroup将不会走onTouchEvent了
  
    * 如果return false,这次action会调用父级View的onTouchEvent。
    * 但是这一次的touch事件之后发出的任何action,该View都不会再接受,onTouchEvent在这一次的touch事件中再也不会触发,
    * 也就是说一旦View返回false,那么之后的ACTION_MOVE,ACTION_UP等ACTION就不会在传入这个View,
    * 但是下一次touch事件的action还是会传进来的。
    * 所以这里要返回true,自己处理所有的ACTION
    * */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }
}

备注:ViewGroup在向View的事件分发中,下面的代码是决定是否分发下去

 if (!canceled && !intercepted) {

                // If the event is targeting accessiiblity focus we give it to the
                // view that has accessibility focus and if it does not handle it
                // we clear the flag and dispatch the event to all children as usual.
                // We are looking up the accessibility focused host to avoid keeping
                // state since these events are very rare.
                View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus()
                        ? findChildWithAccessibilityFocus() : null;

主要关键的是intercepted 这个字段,它是在哪赋值的呢

    final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    **intercepted = onInterceptTouchEvent(ev);**

下面我们就知道了,如果子类要是重写这个onInterceptTouchEvnet就得返回false,如果返回true的话子View 就得不到分发,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值