android - 使用 Jetpack Compose Navigation 导航到另一个 Composable 后记住 List State 的最佳实践
问题描述
当从 Composable A -> Composable B 导航时,说 Composable A 是一个向下滚动的惰性列表,而 Composable B 是一个惰性列表项详细信息屏幕。目前,惰性列表滚动位置没有被存储,当从 B 导航回 Composable A 时,列表从项索引 0 开始。我们可以将它存储在 ViewModel 中,然后读取值,以及使用 rememberSaveable,但是,我不确定如何实现 rememberSaveable 以便在返回导航后滚动到保存的位置。
遵循良好的代码实践,最好使用哪种方法?
编辑:我的问题源于从可组合 B 导航回 A 时未存储 listState。因此,如果我们滚动到底部并选择一个项目并查看其详细信息,当我们导航回列表时它是滚动到顶部,而不是保存它的滚动状态。
我的可组合
val listState = rememberLazyListState()
val showTitle by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}
onShowTitle(showTitle) // don't show title when first list element is visible
LazyColumn(
state = listState,
contentPadding = PaddingValues(16.dp)
) {
item {
Text("Header 1", style = MaterialTheme.typography.h4)
}
item {
Column(Modifier.fillMaxWidth()) {
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
"Description 1",
style = MaterialTheme.typography.subtitle1,
modifier = Modifier.padding(top = 8.dp)
)
}
Spacer(modifier = Modifier.height(48.dp))
}
}
item {
itemOfTheDay.value?.let { item->
ItemCardVertical(
item = item,
navigateToDetails = {
viewModel.selectItem(it)
navigateToDetails(it)
}
)
Spacer(modifier = Modifier.height(48.dp))
}
}
item {
Text("Header 2", style = MaterialTheme.typography.h5)
Spacer(Modifier.size(16.dp))
}
item {
StaggeredVerticalGrid(maxColumnWidth = 220.dp) {
items.value?.forEach { item->
ItemCard(item, navigateToDetails = {
viewModel.selectItem(it)
navigateToDetails(it)
})
}
我的导航图
@Composable
fun NavGraph(startDestination: String = "Items") {
val navController = rememberNavController()
val mainViewModel: MainViewModel = viewModel()
NavHost(navController = navController, startDestination = startDestination) {
navigation(route = "Items", startDestination = MAINSCREEN) {
composable(MAINSCREEN) {
MainScreen(mainViewModel,
navigateToDetails = { smoothie ->
navController.navigate(ITEMSDETAILSSCREEN)
}
)
}
composable(
ITEMDETAILSSCREEN
) {
ItemDetails(
viewModel = mainViewModel, modifier = Modifier
.fillMaxSize()
.navigationBarsPadding()
)
}
}
}
}
解决方案
我会留下这个问题,以防其他人陷入我的境地,但代码按预期工作,我只是犯了一个愚蠢的错误。
我没有考虑异步图像加载时的高度变化,因此,由于列表状态小于返回到可组合时的屏幕高度,因此列表在可组合导航时不会位于其保存的位置。
但是,如果图像被加载到不改变其大小的静态容器中,那么在返回导航时,可组合项将正确显示保存的列表状态。
推荐阅读
- node.js - TypeError:无法在 Function.keys () 处将 undefined 或 null 转换为对象
- javascript - Javascript & PHP 处理
- c++ - lcov 和 gcovr -r 命令正在为 UT 生成 cpp 文件代码覆盖率报告
- flutter - Flutter 中的 Flutter 扩展和 Stateful Widget
- java - 如何根据 $ 修改数组相同的值
- java - 相同的代码,不同的工作(JAVA图形异或模式)
- nginx - 创建 GKE 集群后无法从 Google Cloud Shell 访问 Load Balancer IP
- javascript - html表格行幻灯片
- botframework - 有没有办法在 WebChat 中检查用户输入文本框是否处于活动状态?
- javascript - 内容可编辑 div 的行号