android - Jetpack Compose - 恢复 LazyColumn 滚动状态
问题描述
我有一个LazyColumn
包含多个LazyRow
. 用旧的术语来说,嵌套的 RecyclerView。
我的问题是,LazyColumn
移动到新的可组合(不同的选项卡)时不会恢复滚动状态。但是 inner LazyRow
s 恢复了它们的状态。
例如,打开主屏幕,滚动到底部然后滚动LazyRow
到结束,然后打开不同的选项卡并再次返回主选项卡。LazyColumn
从顶部开始(不恢复状态),但最后LazyRow
恢复它的滚动状态。
主屏幕包含LazyColumn
@Composable
fun HomeScreen(
homeViewModel: HomeViewModel = hiltViewModel()
) {
val scrollState = rememberLazyListState()
LazyColumn(contentPadding = PaddingValues(vertical = 8.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(8.dp),
state = scrollState,
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background)
) {
items(5) {
TopRatedProducts(homeViewModel = homeViewModel)
}
}
}
TopRatedProducts 包含LazyRow
@Composable
fun TopRatedProducts(
homeViewModel: HomeViewModel = hiltViewModel()
) {
val topRatedProducts by rememberFlowWithLifecycle(homeViewModel.topRatedProducts)
.collectAsState(initial = emptyList())
LazyRow(
contentPadding = PaddingValues(horizontal = 8.dp), // Space between start and end
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp), // Space between items
modifier = Modifier
.background(Color.Green)
) {
items(topRatedProducts) {
ProductCardItem(item = it)
}
}
}
如何恢复LazyColumn
滚动状态?
解决方案
当您希望在 Fragments 中使用 ComposeView 这种行为时,您应该提及ViewCompositionStrategy。
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return ComposeView(requireContext()).apply {
// Dispose the Composition when viewLifecycleOwner is destroyed
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnLifecycleDestroyed(viewLifecycleOwner)
)
setContent {
// content
}
}
}
来自文档: 默认情况下,只要视图与窗口分离,Compose 就会处理合成。Compose UI View 类型(如 ComposeView 和 AbstractComposeView)使用定义此行为的 ViewCompositionStrategy。
默认情况下,Compose 使用 DisposeOnDetachedFromWindow 策略。但是,当 Compose UI View 类型用于以下情况时,此默认值可能在某些情况下是不可取的:
片段。组合必须遵循 Fragment 的视图生命周期,以便 Compose UI 视图类型保存状态。
过渡。每当 Compose UI View 被用作转换的一部分时,它将在转换开始时而不是在转换结束时从其窗口中分离,从而导致您的可组合物在它仍在屏幕上时释放其状态。
RecyclerView 视图持有者,或您自己的生命周期管理的自定义视图
文档链接:https ://developer.android.com/jetpack/compose/interop/interop-apis#composition-strategy
推荐阅读
- elasticsearch - 如何将 Solr 集合迁移到 AWS Elasticsearch?
- javascript - 在一个 prop 中配置多个 url 以将子组件传递给 Parent
- python - '字段列表'中的python / MySQL未知列
- visual-studio - Visual Studio 不允许我选择启动项目
- entity-framework - 实体框架总是在表中添加两条记录
- apache-spark - 如何在 PySpark 中用该列的第一个非空值填充该列的空值
- laravel - 如果我使用 API,如何强制 Authenticate.php 中间件响应 json 对象而不返回重定向?我有智威汤逊登录
- git - .gitignore 排除文件夹,除非它在匹配模式的父文件夹中
- java - 将原始位图转换为字节数组
- reactjs - 如何向 Azure 应用授予 Calendar.ReadWrite.Shared 权限?