
Jetpack Compose之持久保存和恢复LazyColumn的滚动位置

简介
默认情况下,LazyColumn
在屏幕进行旋转之后仍然会保持之前滑动的状态,但是一旦应用重新启动,之前滑动的状态则会消失并且从第0条数据显示,下面将介绍如何持久保存和恢复LazyColumn的滚动位置。
示例
首先创建100条模拟数据
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LazyColumnScrollPositionTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
LazyColumn(
state = lazyListState,
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(16.dp)
) {
items(100) {
Text(
text = "Item $it",
modifier = Modifier.padding(16.dp)
)
}
}
}
}
}
}
}
}
创建 SharedPreferences
用于保存数据到本地,然后使用 rememberLazyListState
获取列表滑动的状态,通过 LaunchedEffect
监听它,一旦状态发生改变就会保存最新的状态。
//惰性列表状态
val lazyListState = rememberLazyListState(
initialFirstVisibleItemIndex = xxx//设置初始化位置
)
//监听 lazyListState 的变化
LaunchedEffect(key1 = lazyListState) {
snapshotFlow {
lazyListState.firstVisibleItemIndex
}
.debounce(500L)
.collectLatest { index ->
//println("正在保存滑动下标")
prefs.edit()
.putInt("scroll_position", index)
.apply()
}
}
LazyColumn(
state = lazyListState,
)
//省略部分代码
官方文档解释:网址
使用 snapshotFlow
将 State<T>
对象转换为冷 Flow
。snapshotFlow
会在收集到块时运行该块,并发出从块中读取的 State
对象的结果。当在 snapshotFlow
块中读取的 State
对象之一发生变化时,如果新值与之前发出的值不相等,Flow
会向其收集器发出新值。
snapshotFlow
读取了第一个可见Item的下标转换为流,并且设置了 debounce
为500L,为什么要设置这个呢?原因在于:当用户滑动列表时 lazyListState
会一直进行刷新,例如滑动的次数是80次,那 prefs
要进行80次的保存操作,这样是非常不好的,所以设置500L毫秒的延迟,相当于防抖操作,具体效果可以通过Log查看。
保存的工作就已经做好了,现在就差如何恢复。在 onCreate()
方法中读取保存到的数据,并将其设置到 rememberLazyListState
的 initialFirstVisibleItemIndex
中。
//启动的时候读取上次保存的滚动位置的值
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//启动的时候读取上次保存的滚动位置的值
val scrollPosition = prefs.getInt("scroll_position", 0)
setContent{
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
//惰性列表状态
val lazyListState = rememberLazyListState(
initialFirstVisibleItemIndex = scrollPosition//设置初始化位置
)
//省略部分代码
}
}
运行效果如下:
当我从0滑动到55后,重新打开应用依然是显示的55,说明我们的 LazyColumn
滑动位置恢复成功了。




更多推荐








所有评论(0)