scrollview中嵌套高德地图,触摸冲突解决

今天做的一个页面,要在scrollview中嵌套高德地图,产生触摸冲突,拖动地图和scrollview的滑动事件冲突。

先说一下最终的解决方案。亲测可用。。。

1、自定义一个viewGroup,继承Relativelayout(或者别的layout)
重点是重写了onInterceptTouchEvent(MotionEvent ev)和onTouchEvent(MotionEvent event)

/**
 *解决地图在主scrollview中滑动冲突的问题由于MapView被定义成final class,所以只能在容器中操作了
 Created by 张玉水 on 2016/7/18.
 */

public class MapContainer extends RelativeLayout {
    private ScrollView scrollView;
    public MapContainer(Context context) {
        super(context);
    }

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

    public void setScrollView(ScrollView scrollView) {
        this.scrollView = scrollView;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            scrollView.requestDisallowInterceptTouchEvent(false);
        } else {
            scrollView.requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }
}

2、在布局文件中,用上边定义的父控件包裹住高德地图的com.amap.api.maps2d.MapView.当然最外边是咱们的scrollview。

<com.babyrun.mmsh.widget.MapContainer
     android:id="@+id/map_container"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
      <com.amap.api.maps2d.MapView
          android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="350dp" />
 </com.babyrun.mmsh.widget.MapContainer>

3、在代码中设置一下要关联的Scrollview

 scrollView = (ScrollView) findViewById(R.id.scrollview);
 map_container = (MapContainer) findViewById(R.id.map_container);
 map_container.setScrollView(scrollView);

上边三步做完后就可以完美解决问题。




另附:网上其他方法,都不怎么好用,亲测的。真心的。
一、这个代码网上出现很多次,但真的不管用啊。假的

//       重写onTouch()事件,在事件里通过requestDisallowInterceptTouchEvent(boolean)方法来设置父类的不可用,true表示父类的不可用  
        //解决地图的touch事件和scrollView的touch事件冲突问题  
        mMapView.setOnTouchListener(new View.OnTouchListener() {  

            @Override  
            public boolean onTouch(View v, MotionEvent event) {  
                if(event.getAction() == MotionEvent.ACTION_UP){  
                    scrollView.requestDisallowInterceptTouchEvent(false);  
                }else{  
                    scrollView.requestDisallowInterceptTouchEvent(true);  
                }  
                return false;  
            }  
        });  

如果是ListView嵌套在ScrollView中,解决方法是一样的。

二、重写scrollview,计算布局MapView所在的矩形区域,在矩形区域的时候,屏蔽scrollview的触摸事件的传递。下边的代码,有作用,但是效果不是很好啊。有的时候能动,有的时候不能。

/**
 * Created by 张玉水 on 2016/7/18.
 */
public class LocationScrollView extends ScrollView   {
        public LocationScrollView(Context context) {
            super(context);
        }
        public LocationScrollView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }

        public LocationScrollView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
        }



        private Boolean mIfOnMap = false;//是否点击到地图了

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev)
        {

            int x = (int) ev.getX();
            int y = (int) ev.getY();
            Rect rect = new Rect();
            if (ServiceLocationActivity.mapView != null) {
                ServiceLocationActivity.mapView.measure(0,0);
                ServiceLocationActivity.mapView.getDrawingRect(rect);
            }

            mIfOnMap = !rect.contains(x, y);
            if (mIfOnMap) {
                return false;
            }else {
                return super.onInterceptTouchEvent(ev);
            }
        }



    //    //得到view到 屏幕的距离
//    public int[] getLocation(View v) {
//        int[] loc = new int[4];
//        int[] location = new int[2];
//        v.getLocationOnScreen(location);
//        loc[0] = location[0];
//        loc[1] = location[1];
//        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
//        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
//        v.measure(w, h);
//
//        loc[2] = v.getMeasuredWidth();
//        loc[3] =  v.getMeasuredHeight()+loc[1];//底部距离 屏幕上边的 高
//
//        int [] up_down=new int[2];
//        up_down[0]=loc[1];//上边距离屏幕的距离
//        up_down[1]=loc[3];// 底部距离屏幕的距离
//        //base = computeWH();
//        return up_down;
//    }

    }
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
在 iOS 开发嵌套在 `UIScrollView` 的 `UITableView` 在滑动时可能会与 `UIScrollView` 的滑动手势产生冲突,导致无法正常滑动。这个问题可以通过以下两种方式解决: 1. 禁用 `UIScrollView` 的滑动手势 可以通过设置 `UIScrollView` 的 `panGestureRecognizer` 的 `enabled` 属性为 `NO` 来禁用滑动手势,这样就不会与 `UITableView` 的滑动手势产生冲突了。 ```objc scrollView.panGestureRecognizer.enabled = NO; ``` 2. 实现 `UIGestureRecognizerDelegate` 协议的方法 在 `UIViewController` 实现 `UIGestureRecognizerDelegate` 协议的 `gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:` 方法,可以控制两个手势是否允许同时识别。在这个方法,可以判断当前的手势是否为 `UIScrollView` 的滑动手势,如果是,则允许与 `UITableView` 的滑动手势同时识别,否则不允许。 ```objc - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if ([gestureRecognizer.view isKindOfClass:[UIScrollView class]] && [otherGestureRecognizer.view isKindOfClass:[UITableView class]]) { return YES; } return NO; } ``` 需要注意的是,在实现这个方法时,要将 `UIScrollView` 的 `delegate` 设置为当前的 `UIViewController`,否则这个方法不会被调用。 ```objc scrollView.delegate = self; ``` 以上两种方式都可以解决嵌套在 `UIScrollView` 的 `UITableView` 滑动手势冲突的问题。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值