6

当我从一个可组合屏幕导航到另一个屏幕时,我正在尝试保存/记住 LazyColumn 滚动位置。即使我将 rememberLazyListState 传递给 LazyColumn,在我返回第一个可组合屏幕后滚动位置也不会保存。有人可以帮我吗?

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

2 回答 2

3

好吧,如果您真的想保存它,则必须将其存储为类似于视图模型的东西,它仍然保留。ed的remember东西只会持续到 Composable 被销毁。如果您导航到另一个屏幕,则先前的 Composable 将被销毁,并且滚动状态也会随之销毁

于 2021-08-01T15:23:30.330 回答
1
/**
 * 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")
)
于 2022-02-15T08:30:46.537 回答