AuS*_*ike 8 android google-maps android-jetpack android-jetpack-compose
我正在尝试构建一个可导航到多个不同屏幕的应用程序(使用底部导航)。其中一个屏幕,startDestination
,是 Google 地图视图,查看官方撰写示例:Crane使其工作,并且确实如此。
然而,当导航到另一个屏幕并返回时,画面MapView
会重新构图并缓慢加载回来。我们从初始相机位置、缩放级别等开始。可能有一种方法可以remember
重新应用这些属性,但我更感兴趣的是保持 Google 地图视图的完整状态不变。(看看当前的 Android 版 Google 地图应用程序,它完全符合我的要求,尽管它们没有使用 Jetpack Compose)
有办法实现这一点吗?
我remember
已经MapView
@Composable
fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context).apply {
id = R.id.map
}
}
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle, mapView) {
// Make MapView follow the current lifecycle
val lifecycleObserver = getMapLifecycleObserver(mapView)
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return mapView
}
private fun getMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
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()
}
}
Run Code Online (Sandbox Code Playgroud)
为了提供更多上下文,MapView
位于此屏幕的顶部
@ExperimentalMaterialApi
@Composable
fun MapsScreen(
modifier: Modifier = Modifier,
viewModel: EventViewModel = viewModel()
) {
...
val mapView = rememberMapViewWithLifecycle()
MapsScreenView(modifier, uiState, mapView)
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的一种完全不同的方法是通过 a BackdropScaffold
(在a中Scaffold
,因为我想要BottomBar
..) 其中backLayerContent
和MapsScreen()
是frontLayerContent
其他屏幕,配置“前面”,以便在活动时它将覆盖整个屏幕。感觉真的很丑陋和可怕,但它有点管用..
Scaffold(
topBar = {
SmallTopAppBar(
title = { Text(text = "Test") },
)
},
bottomBar = {
BottomBar(navController) { screen ->
showMaps = screen == Screen.MainMaps
coroutineScope.launch {
if (showMaps) scaffoldState.reveal() else scaffoldState.conceal()
}
}
},
content = { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
BackdropScaffold(
scaffoldState = scaffoldState,
appBar = { },
frontLayerContent = {
EventsScreen()
},
backLayerContent = {
MapsScreen()
},
peekHeight = if (showMaps) 300.dp else 0.dp,
headerHeight = if (showMaps) BackdropScaffoldDefaults.HeaderHeight else 0.dp,
gesturesEnabled = showMaps
)
}
}
)
Run Code Online (Sandbox Code Playgroud)
有人遇到同样的问题并找到实际的解决方案吗?(我猜我们确实需要 Jetpack Compose 支持,而不是这种方法AndroidView
)
Google 刚刚发布了一个库来处理 MapView 状态Android-Maps-Compose
val cameraPositionState: CameraPositionState = rememberCameraPositionState()
GoogleMap(cameraPositionState = cameraPositionState)
Button(onClick = { cameraPositionState.move(CameraUpdateFactory.zoomIn()) }) {
Text(text = "Zoom In")
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2378 次 |
最近记录: |