携手创作,一起生长!这是我参加「日新方案 8 月更文挑战」的第3天,点击查看活动概况。

Compose中咱们应该怎么运用地图呢?像之前咱们在xml里边创建MapView,都是在Activity里边,管理MapView生命周期,和其他的监听器,Compose里边怎么搞?

下面咱们以高德地图为例,在Compose中创建地图MapView,然后用AndroidView增加MapView,像下面这样:

AndroidView(modifier = Modifier, factory = { MapView }){...}

咱们看到,高德地图官网,给开发者的主张:

Compose里边怎么运用地图,比方高德地图

所以咱们需求做什么,咱们晓得了哇,生命周期回调咱们要拿到,那咱们应该怎么搞? 咱们需求用到LocalLifecycleOwner.current.lifecycle去增加生命周期观察者, LifecycleObserver是一个接口,它长下面这样:

Compose里边怎么运用地图,比方高德地图

咱们看注释能够看到,咱们能够运用DefaultLifecycleObserver或许LifecycleEventObserverDefaultLifecycleObserver里边它供给了一切的生命周期工作的回调,而且默认情况下都是什么都不做。 LifecycleEventObserver,它供给了一个onStateChanged办法,一切的生命周期工作都能够在这里被接受到。

所以,咱们这里就运用LifecycleEventObserver,为啥懂的都懂。

咱们有了2个需求初始化的东西,一个是MapView,一个是增加生命周期观察者。

为什么要增加生命周期观察者,看了上面的官方文档应该知道是为什么,是需求管理地图的生命周期,下面咱们来讲讲怎么做,该怎么做。

初始化MapView并增加到AndroidView里边:

val context = LocalContext.current
// aMapOptionsFactory: () -> AMapOptions = { AMapOptions() }
val mapView = remember { 
   MapView(context, aMapOptionsFactory()).apply{ 
      id = R.id.map
   }
}
// 增加MapView
AndroidView(modifier = modifier, factory = { mapView })

咱们来拆解一下,怎么增加生命周期管理者,咱们给咱们聊聊:registerComponentCallbacks,这个ComponentCallbacks里边供给了2个办法: onConfigurationChangedonLowMemory

onConfigurationChanged: 设备装备产生改变,组件还在运转时

onLowMemory:系统运转的内存不足时,能够通过完成该办法去开释内存或不需求的资源,咱们需求在这个办法里边,调用MapView#onLowMemory

在上面官方文档中,咱们看到地图的生命周期管理,需求调用下面4个办法: MapView#onCreateMapView#onResumeMapView#onPauseMapView#onDestory,有了这些序幕,咱们就知道怎么写地图生命周期的扩展办法了。

MapView增加一个管理地图生命周期的扩展:

// 管理地图生命周期
private fun MapView.lifecycleObserver(): LifecycleEventObserver =
    LifecycleEventObserver { _, event ->
        when (event) {
            Lifecycle.Event.ON_CREATE -> this.onCreate(Bundle())
            Lifecycle.Event.ON_RESUME -> this.onResume() // 重新制作加载地图
            Lifecycle.Event.ON_PAUSE -> this.onPause()  // 暂停地图的制作
            Lifecycle.Event.ON_DESTROY -> this.onDestroy() // 销毁地图
            else -> {}
        }
    }
private fun MapView.componentCallbacks(): ComponentCallbacks =
    object : ComponentCallbacks {
        // 设备装备产生改变,组件还在运转时
        override fun onConfigurationChanged(config: Configuration) {}
        // 系统运转的内存不足时,能够通过完成该办法去开释内存或不需求的资源
        override fun onLowMemory() {
            // 调用地图的onLowMemory
            this@componentCallbacks.onLowMemory()
        }
    }

给MapView增加生命周期观察者:


@Composable
private fun MapLifecycle(mapView: MapView) {
    val context = LocalContext.current
    val lifecycle = LocalLifecycleOwner.current.lifecycle
    DisposableEffect(context, lifecycle, mapView) {
        val mapLifecycleObserver = mapView.lifecycleObserver()
        val callbacks = mapView.componentCallbacks()
        // 增加生命周期观察者
        lifecycle.addObserver(mapLifecycleObserver)
        // 注册ComponentCallback
        context.registerComponentCallbacks(callbacks)
        onDispose {
            // 删除生命周期观察者
            lifecycle.removeObserver(mapLifecycleObserver)
            // 取消注册ComponentCallback
            context.unregisterComponentCallbacks(callbacks)
        }
    }
}

运用起来也很简单,先初始化MapView然后增加到AndroidView,最后增加MapView的生命周期操控:

val context = LocalContext.current
val mapView = remember { 
   MapView(context, aMapOptionsFactory()).apply{ 
      id = R.id.map
   }
}
AndroidView(modifier = modifier, factory = { mapView })
MapLifecycle(mapView)

这样只能说满意咱们的正常地图显现,实际上咱们开发过程中,常见的地图拖拽选点定位蓝点标记位等都需求咱们去扩展。

地图拖拽选点功用来说,咱们就需求在MapLifecycle增加2个生命周期的回调,onResumeonPause

MapLifecycle(
  mapView = mapView,
  // 从mapView.lifecycleObserver回调回来即可
  onResume = {
      mapView.map.apply{
         setOnMapLoadedListener(...)
         setOnCameraChangeListener(...)
      }
  },
  onPause = {
      mapView.map.apply{
         setOnMapLoadedListener(null)
         setOnCameraChangeListener(null)
      }
  }
)

剩下的功用,都是拿AMap对象去做工作,增加覆盖物移动相机镜头等等。

注意: 初始化地图的时分,传入的aMapOptionsFactory,能够从外面初始化好传进来。

aMapOptionsFactory: () -> AMapOptions = { AMapOptions() }

Compose里边怎么运用地图,比方高德地图

Compose集成的高德地图作用

有其他问题,能够评论区交流。