Android开发Compose集成高德地图实例

作者:Halifax 时间:2022-09-05 01:44:28 

Compose中我们应该怎么使用地图呢?像之前我们在xml里面创建MapView,都是在Activity里面,管理MapView生命周期,和其他的 * ,Compose里面怎么搞?

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

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

高德地图官网开发者建议

我们看到,高德地图官网,给开发者的建议:

Android开发Compose集成高德地图实例

所以我们需要做什么,大家晓得了哇,生命周期回调我们要拿到,那我们应该怎么搞?

我们需要用到LocalLifecycleOwner.current.lifecycle去添加生命周期观察者, LifecycleObserver是一个接口,它长下面这样:

Android开发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的生命周期控制

使用起来也很容易,先初始化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() }

Android开发Compose集成高德地图实例

Compose集成的高德地图效果

来源:https://juejin.cn/post/7135435381209579556

标签:Android,Compose,地图集成,高德地图
0
投稿

猜你喜欢

  • 基于synchronized修饰静态和非静态方法

    2021-10-30 06:58:03
  • Java实现远程控制技术完整源代码分享

    2022-04-10 20:31:53
  • 代码分析Android消息机制

    2023-07-26 09:44:44
  • java基础的详细了解第五天

    2023-06-02 16:54:04
  • Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)

    2022-07-31 14:39:23
  • Java中使用Lambda表达式和函数编程示例

    2022-05-06 03:30:40
  • struts2自定义拦截器的示例代码

    2021-12-01 16:24:52
  • SpringMVC + servlet3.0 文件上传的配置和实现代码

    2023-08-08 16:42:43
  • Java花式解决'分割回文串 ii'问题详解

    2022-07-09 02:01:58
  • C#条件拼接Expression<Func<T, bool>>的使用

    2023-07-11 22:29:18
  • 如何利用JAVA实现走迷宫程序

    2022-06-23 10:52:06
  • 解决unity rotate旋转物体 限制物体旋转角度的大坑

    2022-01-14 01:41:49
  • SpringBoot统一响应格式及统一异常处理

    2022-08-30 08:03:08
  • C#实现让ListBox适应最大Item宽度的方法

    2022-06-30 16:41:26
  • 在Java中使用redisTemplate操作缓存的方法示例

    2023-07-04 09:03:28
  • Spring Batch入门教程篇

    2022-02-15 01:53:01
  • Java服务限流算法的6种实现

    2022-04-03 04:52:51
  • java中addMouseListener()方法的使用

    2021-07-07 19:29:35
  • JavaWeb 中Cookie实现记住密码的功能示例

    2023-04-06 05:06:48
  • Java List集合排序实现方法解析

    2023-01-06 05:40:14
  • asp之家 软件编程 m.aspxhome.com