Google 地图加载时如何在 Jetpack Compose 中显示加载微调器?
How show loading spinner in Jetpack Compose while Google Maps load?
根据 Internet 上的几个教程,我成功地在我的应用程序中绘制了 Google 地图:
@Composable
fun MyMap(
lat: Double,
lon: Double
) {
val mapView = rememberMapViewWithLifeCycle()
Column(
modifier = Modifier
.background(Color.White)
) {
AndroidView(
{ mapView }
) { mapView ->
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
map.uiSettings.isZoomControlsEnabled = false
val destination = LatLng(lat, lon)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination, 16f))
val markerOptionsDestination = MarkerOptions()
.position(destination)
map.addMarker(markerOptionsDestination)
map.mapType = com.google.android.libraries.maps.GoogleMap.MAP_TYPE_HYBRID
}
}
}
}
@Composable
fun rememberMapViewWithLifeCycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context).apply {
id = R.id.map_frame
}
}
val lifeCycleObserver = rememberMapLifecycleObserver(mapView)
val lifeCycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifeCycle) {
lifeCycle.addObserver(lifeCycleObserver)
onDispose {
lifeCycle.removeObserver(lifeCycleObserver)
}
}
return mapView
}
@Composable
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
}
我从另一个有更多元素(如文本等)的可组合项加载此可组合项:
@Composable
fun MyMain() {
Box(
modifier = Modifier
.fillMaxWidth()
.size(300.dp)
) {
MyMap(lat, lon)
}
}
地图加载需要时间,不长,可能1秒或更短。但我希望 MyMain 可组合项而不是第二个空框(包含地图的框),以显示加载微调器。我该如何实施?
你或许可以这样做:
如果在 mapView.awaitMap() 之后地图实际上没有完全加载,请尝试用 delay(1000) 替换该行。 (或超过 1000 毫秒)
@Composable
fun MyMap(
lat: Double,
lon: Double,
) {
val mapView = rememberMapViewWithLifeCycle()
var isMapLoading by remember { mutableStateOf(true) }
LaunchedEffect(mapView) {
mapView.awaitMap()
isMapLoading = false
}
Box {
AndroidView(
{ mapView }
) { mapView ->
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
map.uiSettings.isZoomControlsEnabled = false
val destination = LatLng(lat, lon)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination, 16f))
val markerOptionsDestination = MarkerOptions()
.position(destination)
map.addMarker(markerOptionsDestination)
map.mapType = com.google.android.libraries.maps.GoogleMap.MAP_TYPE_HYBRID
}
}
if (isMapLoading) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.matchParentSize()
.background(Color.White)
) {
CircularProgressIndicator()
}
}
}
}
根据 Internet 上的几个教程,我成功地在我的应用程序中绘制了 Google 地图:
@Composable
fun MyMap(
lat: Double,
lon: Double
) {
val mapView = rememberMapViewWithLifeCycle()
Column(
modifier = Modifier
.background(Color.White)
) {
AndroidView(
{ mapView }
) { mapView ->
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
map.uiSettings.isZoomControlsEnabled = false
val destination = LatLng(lat, lon)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination, 16f))
val markerOptionsDestination = MarkerOptions()
.position(destination)
map.addMarker(markerOptionsDestination)
map.mapType = com.google.android.libraries.maps.GoogleMap.MAP_TYPE_HYBRID
}
}
}
}
@Composable
fun rememberMapViewWithLifeCycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context).apply {
id = R.id.map_frame
}
}
val lifeCycleObserver = rememberMapLifecycleObserver(mapView)
val lifeCycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifeCycle) {
lifeCycle.addObserver(lifeCycleObserver)
onDispose {
lifeCycle.removeObserver(lifeCycleObserver)
}
}
return mapView
}
@Composable
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
}
我从另一个有更多元素(如文本等)的可组合项加载此可组合项:
@Composable
fun MyMain() {
Box(
modifier = Modifier
.fillMaxWidth()
.size(300.dp)
) {
MyMap(lat, lon)
}
}
地图加载需要时间,不长,可能1秒或更短。但我希望 MyMain 可组合项而不是第二个空框(包含地图的框),以显示加载微调器。我该如何实施?
你或许可以这样做:
如果在 mapView.awaitMap() 之后地图实际上没有完全加载,请尝试用 delay(1000) 替换该行。 (或超过 1000 毫秒)
@Composable
fun MyMap(
lat: Double,
lon: Double,
) {
val mapView = rememberMapViewWithLifeCycle()
var isMapLoading by remember { mutableStateOf(true) }
LaunchedEffect(mapView) {
mapView.awaitMap()
isMapLoading = false
}
Box {
AndroidView(
{ mapView }
) { mapView ->
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
map.uiSettings.isZoomControlsEnabled = false
val destination = LatLng(lat, lon)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination, 16f))
val markerOptionsDestination = MarkerOptions()
.position(destination)
map.addMarker(markerOptionsDestination)
map.mapType = com.google.android.libraries.maps.GoogleMap.MAP_TYPE_HYBRID
}
}
if (isMapLoading) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.matchParentSize()
.background(Color.White)
) {
CircularProgressIndicator()
}
}
}
}