Billy Newman
06/06/2022, 3:42 PMBilly Newman
06/06/2022, 3:44 PM@Composable
private fun Map(
markers: List<MapMarker>
) {
val context = LocalContext.current
val mapView = remember { MapView(context) }
MapLifecycle(mapView)
var previousMarkers by remember { mutableStateOf(listOf<MapMarker>()) }
var mapInitialized by remember { mutableStateOf(false) }
LaunchedEffect(mapView, mapInitialized) {
if (!mapInitialized) {
val map = mapView.awaitMap()
map.uiSettings.isMapToolbarEnabled = false
mapInitialized = true
}
}
LaunchedEffect(mapInitialized, markers) {
if (mapInitialized) {
val map = mapView.awaitMap()
// add new
// update existing
// remove old
}
}
AndroidView({ mapView })
}
@Composable
private fun MapLifecycle(mapView: MapView) {
val context = LocalContext.current
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(context, lifecycle, mapView) {
val mapLifecycleObserver = mapView.lifecycleObserver()
lifecycle.addObserver(mapLifecycleObserver)
onDispose {
lifecycle.removeObserver(mapLifecycleObserver)
}
}
}
private fun MapView.lifecycleObserver(): LifecycleEventObserver =
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> this.onCreate(Bundle())
Lifecycle.Event.ON_START -> this.onStart()
Lifecycle.Event.ON_RESUME -> this.onResume()
Lifecycle.Event.ON_PAUSE -> this.onPause()
Lifecycle.Event.ON_STOP -> this.onStop()
Lifecycle.Event.ON_DESTROY -> this.onDestroy()
else -> throw IllegalStateException()
}
}
Colton Idle
06/06/2022, 4:00 PMColton Idle
06/06/2022, 4:01 PMBilly Newman
06/06/2022, 4:37 PMChris Arriola
06/06/2022, 5:11 PMClusterManager
had a contains
function, you can at least do a check before adding an itemColton Idle
06/06/2022, 5:14 PMcontains
method.Billy Newman
06/06/2022, 5:48 PMvar previousMarkers by remember { mutableStateOf(listOf<MapMarker>()) }
var clusterManager by remember { mutableStateOf<ClusterManager?>(null)}
LaunchedEffect(mapView, markers) {
if (clusterManager == null) {
val map = mapView.awaitMap().apply {
uiSettings.isMapToolbarEnabled = false
}
clusterManager = // init cluster manager with map
}
var updateCluster = false
val manager = clusterManager
if (manager != null) {
val markerSet = markers.toSet()
val previousMarkerSet = previousMarkers.toSet()
// add new
markerSet.minus(previousMarkerSet).forEach {
manager.addItem(it)
updateCluster = true
}
// update existing
markerSet.intersect(previousMarkerSet).forEach {
manager.updateItem(it)
updateCluster = true
}
// remove old
previousMarkerSet.minus(markerSet).forEach {
manager.removeItem(it)
updateCluster = true
}
if (updateCluster) {
manager.cluster()
previousMarkers = markers
}
}
}
Chris Arriola
06/06/2022, 5:59 PMBilly Newman
06/06/2022, 6:15 PMColton Idle
06/06/2022, 6:19 PMColton Idle
06/06/2022, 6:20 PMColton Idle
06/06/2022, 6:20 PMChris Arriola
06/06/2022, 6:24 PMMapView
. a possible workaround is to add a key to the remember
for MapView
so a new instance is created when you navigate backBilly Newman
06/06/2022, 6:43 PMI/Map lifecycle event: ON_CREATE
I/Map lifecycle event: ON_START
I/Map lifecycle event: ON_RESUME
on navigate away from map:
I/Map lifecycle event: ON_PAUSE
I/Map lifecycle event: ON_STOP
on navigate back to map:
I/Map lifecycle event: ON_CREATE
I/Map lifecycle event: ON_DESTROY
I/Map lifecycle event: ON_CREATE
I/Map lifecycle event: ON_START
I/Map lifecycle event: ON_RESUME
Interesting, so looks like on navigation back a additional create and destroy are calledChris Arriola
06/06/2022, 8:41 PMBilly Newman
06/06/2022, 9:45 PMColton Idle
06/06/2022, 11:02 PMBilly Newman
06/07/2022, 12:25 AMChris Arriola
06/07/2022, 12:33 AMBilly Newman
06/07/2022, 2:00 AMBilly Newman
06/07/2022, 2:02 AMBilly Newman
06/07/2022, 2:15 AMChris Arriola
06/07/2022, 4:25 AMColton Idle
06/07/2022, 10:32 AMColton Idle
06/07/2022, 10:43 AMColton Idle
06/07/2022, 10:47 AMColton Idle
06/07/2022, 10:48 AMColton Idle
06/18/2022, 3:44 AMChris Arriola
06/18/2022, 5:14 AMChris Arriola
06/18/2022, 5:14 AMColton Idle
06/20/2022, 3:12 PMChris Arriola
06/20/2022, 3:32 PMColton Idle
06/20/2022, 3:36 PMChris Arriola
06/20/2022, 3:42 PMChris Arriola
06/20/2022, 3:42 PMColton Idle
06/20/2022, 3:43 PMChris Arriola
06/20/2022, 3:46 PM