【问题标题】:Keeping the Google Maps state in Jetpack Compose在 Jetpack Compose 中保持 Google 地图状态
【发布时间】:2022-01-08 10:21:29
【问题描述】:

我正在尝试构建一个可以导航到多个不同屏幕的应用程序(使用底部导航)。 其中一个屏幕,startDestination,是一个谷歌地图视图,查看Official compose example: Crane 以使其工作,它确实如此。

但是,当导航到另一个屏幕并返回时,MapView 会重新组合并缓慢重新加载。我们从初始相机位置、缩放级别等开始返回。可能有一种方法可以remember 并重新应用这些属性,但我更感兴趣的是保持 Google 地图视图的完整状态不变。 (查看当前适用于 Android 的 Google Maps 应用程序,它完全符合我的要求,尽管他们没有使用 Jetpack Compose)

有没有办法做到这一点?

我已经rememberMapView

@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()
        }
    }

为了提供更多上下文,MapView 位于此屏幕的顶部

@ExperimentalMaterialApi
@Composable
fun MapsScreen(
    modifier: Modifier = Modifier,
    viewModel: EventViewModel = viewModel()
) {
    ...
    val mapView = rememberMapViewWithLifecycle()
    MapsScreenView(modifier, uiState, mapView)
}

我尝试过的完全不同的方法是通过BackdropScaffoldinScaffold,因为我想要BottomBar..),其中backLayerContentMapsScreen()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
            )
        }
    }
)

有没有人遇到同样的问题并找到了实际的解决方案? (我猜我们真的需要 Jetpack Compose 支持,而不是 AndroidView 方法)

【问题讨论】:

标签: android google-maps android-jetpack-compose android-jetpack


【解决方案1】:

观看此codingwithmitch 插曲,您可能会从中受益,该插曲有关处理谷歌地图与大型数据集的状态。任何,不想破坏故事,但它包括视图模型......

https://www.youtube.com/watch?v=J8OqN-JqWlQ&t=1s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 2021-03-05
    相关资源
    最近更新 更多