![](/img/trans.png)
[英]Jetpack Compose LazyColumn recomposition with remember()
[英]Remember LazyColumn Scroll Position - Jetpack Compose
当我从一个可组合屏幕导航到另一个时,我试图保存/记住 LazyColumn 滚动条 position。 即使我将 rememberLazyListState 传递给 LazyColumn,在我返回第一个可组合屏幕后,滚动条 position 也不会保存。 有人可以帮我吗?
@ExperimentalMaterialApi
@Composable
fun DisplayTasks(
tasks: List<Task>,
navigateToTaskScreen: (Int) -> Unit
) {
val listState = rememberLazyListState()
LazyColumn(state = listState) {
itemsIndexed(
items = tasks,
key = { _, task ->
task.id
}
) { _, task ->
LazyColumnItem(
toDoTask = task,
navigateToTaskScreen = navigateToTaskScreen
)
}
}
}
/**
* Static field, contains all scroll values
*/
private val SaveMap = mutableMapOf<String, KeyParams>()
private data class KeyParams(
val params: String = "",
val index: Int,
val scrollOffset: Int
)
/**
* Save scroll state on all time.
* @param key value for comparing screen
* @param params arguments for find different between equals screen
* @param initialFirstVisibleItemIndex see [LazyListState.firstVisibleItemIndex]
* @param initialFirstVisibleItemScrollOffset see [LazyListState.firstVisibleItemScrollOffset]
*/
@Composable
fun rememberForeverLazyListState(
key: String,
params: String = "",
initialFirstVisibleItemIndex: Int = 0,
initialFirstVisibleItemScrollOffset: Int = 0
): LazyListState {
val scrollState = rememberSaveable(saver = LazyListState.Saver) {
var savedValue = SaveMap[key]
if (savedValue?.params != params) savedValue = null
val savedIndex = savedValue?.index ?: initialFirstVisibleItemIndex
val savedOffset = savedValue?.scrollOffset ?: initialFirstVisibleItemScrollOffset
LazyListState(
savedIndex,
savedOffset
)
}
DisposableEffect(Unit) {
onDispose {
val lastIndex = scrollState.firstVisibleItemIndex
val lastOffset = scrollState.firstVisibleItemScrollOffset
SaveMap[key] = KeyParams(params, lastIndex, lastOffset)
}
}
return scrollState
}
使用示例
LazyColumn(
state = rememberForeverLazyListState(key = "Overview")
)
好吧,如果您真的想保存它,则必须将其存储为类似视图模型的东西,并且它仍然保留下来。 remember
东西只持续到可组合被销毁。 如果您导航到另一个屏幕,则先前的 Composable 将被销毁,并且滚动状态也会随之销毁
@Composable
fun persistedScrollState(viewModel: ParentViewModel): ScrollState {
val scrollState = rememberScrollState(viewModel.scrollPosition)
DisposableEffect(key1 = null) {
onDispose {
viewModel.scrollPosition = scrollState.value
}
}
return scrollState
}
上面我定义了一个辅助函数,用于在处理可组合项时保持滚动状态。 所需要的只是一个带有滚动位置变量的 ViewModel。
希望这对某人有帮助!
Column(modifier = Modifier
.fillMaxSize()
.verticalScroll(
persistedScrollState(viewModel = viewModel)
) {
//Your content here
}
@Composable
fun persistedLazyScrollState(viewModel: YourViewModel): LazyListState {
val scrollState = rememberLazyListState(viewModel.firstVisibleItemIdx, viewModel.firstVisibleItemOffset)
DisposableEffect(key1 = null) {
onDispose {
viewModel.firstVisibleItemIdx = scrollState.firstVisibleItemIndex
viewModel.firstVisibleItemOffset = scrollState.firstVisibleItemScrollOffset
}
}
return scrollState
}
}
在上面,我定义了一个帮助程序 function 以在处置可组合项时保留滚动条 state。 所需要的只是一个带有 firstVisibleItemIdx 和 firstVisibleItemOffet 变量的 ViewModel。
Column(modifier = Modifier
.fillMaxSize()
.verticalScroll(
persistedScrollState(viewModel = viewModel)
) {
//Your content here
}
导航到下一个屏幕时, LazyColumn
应该立即保存滚动条 position。 如果它不起作用,这可能是此处描述的错误(问题跟踪器)。 基本上检查列表是否在更改屏幕时变空,例如,因为您观察到冷流或 LiveData(因此使用初始值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.