注册

现在的位置是: 小猿圈 > Jetpack Compose之持久保存和恢复LazyColumn的滚动位置_jetpack的compose中设置lazycolumn滚动到最底部

Jetpack Compose之持久保存和恢复LazyColumn的滚动位置_jetpack的compose中设置lazycolumn滚动到最底部

vickytang2024-12-27 11:54:02.0234人围观
版权声明 本文转自https://blog.csdn.net/weixin_49767743/article/details/133636308,版权归原作者所有。如有侵权,请联系删除,谢谢。

简介

默认情况下,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,//省略部分代码

官方文档解释:网址

使用 snapshotFlowState<T> 对象转换为冷 FlowsnapshotFlow 会在收集到块时运行该块,并发出从块中读取的 State 对象的结果。当在 snapshotFlow 块中读取的 State 对象之一发生变化时,如果新值与之前发出的值不相等,Flow 会向其收集器发出新值。

snapshotFlow 读取了第一个可见Item的下标转换为流,并且设置了 debounce 为500L,为什么要设置这个呢?原因在于:当用户滑动列表时 lazyListState 会一直进行刷新,例如滑动的次数是80次,那 prefs 要进行80次的保存操作,这样是非常不好的,所以设置500L毫秒的延迟,相当于防抖操作,具体效果可以通过Log查看。

保存的工作就已经做好了,现在就差如何恢复。在 onCreate() 方法中读取保存到的数据,并将其设置到 rememberLazyListStateinitialFirstVisibleItemIndex 中。

//启动的时候读取上次保存的滚动位置的值
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 滑动位置恢复成功了。
在这里插入图片描述