前言
由于高德地图sdk开始涨价割韭菜了,因此,我司在降本增效的大背景下,需要把高德地图换成腾讯地图。
在更换sdk过程中,踩了一些关于地图手势事件的坑,这里记录下,希望能给遇到同样问题的大佬们一个思路。
拖动地图失效,地图无响应
由于用到地图的页面是RN的,因此,native这边主要是提供一个地图控件,实现RN所需的对应api。
我这边是直接继承自 TextureMapView
实现了一个自定义的 MapView,然后把自定义的MapView 暴露出去给RN使用。然后就是把之前用高德的api换成腾讯的api同步实现即可。
按照这个思路写完代码后,测试地图可以正常显示,心想,这不是信手拈来,美滋滋。
于是顺手划了下地图,发现地图一动不动,就像是触摸事件失效了一样。
没错,悲伤总是来的那么快。
高德地图就没问题啊,同样的代码这是换成了腾讯地图,怎么就不响应手势了呢?
一开始以为是自己哪里配置的有问题,于是去扒了下官方文档,没发现有什么问题啊。
回过头来想了一下,是不是事件被子view拦截并消费掉了,导致当前这个mapview拿不到事件?于是,直接重写 onInterceptTouchEvent
默认返回true,强制让当前 View
拦截所有的触摸事件。
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {return true}
再次运行,地图可以响应拖动以及点击事件了。
嗯,so easy!
随后换了个页面测试,又发现地图似乎拖动起来很困难,还有事件冲突,因为这个页面整体是一个可滚动的View,内部的顶上嵌套了一个MapView,这就导致了我明明移动的是地图,结果整个页面都跟着向上滑动了,而不是预期的mapView内部本身进行滑动。
这不就是典型的事件被父view给拦截处理导致事件冲突了吗?
在翻阅腾讯地图的文档时发现 TencentMapOptions
有个配置可以设置父视图不要拦截事件。
于是,按照文档加了配置。
TencentMapOptions().apply {setDisallowInterceptTouchEvent(false)//允许拦截触摸事件}
再次运行测试发现,毛用没有!
这…
没办法,直接扒源码打断点看下啥情况了,直接看他内部事件分发的处理逻辑,如下
在断点时发现,super.dispatchTouchEvent(ev)
的返回值是 true,也就是说根本就走不到里面 mMapDelegate.onTouchEvent(ev)
的逻辑,怪不得之前地图不响应手势了。
找到问题就简单了,把之前onInterceptTouchEvent
的代码干掉,直接重写 dispatchTouchEvent
,然后直接返回mMapDelegate.onTouchEvent(ev)
让mMapDelegate
去处理事件即可。
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {Logger.it(TAG, "dispatchTouchEvent:${ev}")return mMapDelegate.onTouchEvent(ev)}
再次运行测试,好了…
本篇文章就是这样,希望给遇到同样问题的大佬们一点思路吧,希望能够帮助到大家。
感谢阅读,如果对你有帮助请三连(点赞、收藏、加关注)支持。有任何疑问或建议,欢迎在评论区留言讨论。如需转载,请注明出处:喻志强的博客