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,//省略部分代码

官方文档解释:网址

使用 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 滑动位置恢复成功了。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Jetpack Compose 是一个全新的 Android UI 框架,其基本的组成单元是函数式组件,它们由一些输入参数和一个返回 UI 元素的函数组成。Jetpack Compose 可以让开发者更加简单地创建漂亮的、响应式的 UI。 在 Jetpack Compose ,mutableStateOf 是一个非常重要的概念。它是一个可变的状态值,当它的值变化时,会自动重绘 UI。REMBER 是一个包含一个函数和一个可变状态的函数式组件,它可以用来保存和更新状态。 下面是一个使用 mutableStateOf 和 REMBER 的 Jetpack Compose 代码示例: ```kotlin @Composable fun Counter() { val count = remember { mutableStateOf(0) } // 定义一个可变状态值 Button(onClick = { count.value++ }) { Text("Count: ${count.value}") } } ``` 在这个例子,我们定义了一个 Counter 函数式组件,它包含一个可变状态值 count。我们使用 REMBER 函数来保存 count 状态,并使用 mutableStateOf 来定义 count 的初始值为 0。 在 Button 的 onClick 回调,我们使用 count.value++ 来增加 count 的值。由于 count 是一个 mutableStateOf 对象,当它的值改变时,Jetpack Compose 会自动重绘 UI,以显示新的值。 总之,Jetpack Compose 的 mutableStateOf 和 REMBER 非常有用,它们可以帮助我们轻松地创建响应式的 UI,同时也可以帮助我们管理组件状态和更新 UI。 ### 回答2: Jetpack Compose 是一种全新的Android UI工具包,它使开发者能够使用简单明了的声明方式构建用户界面。在Jetpack Compose,我们可以使用mutableStateOf和remember来处理界面状态和保存组件的状态。 mutableStateOf是Compose的一个函数,用于创建可变的状态变量。它接受一个初始值,并返回一个包含值和更新函数的State对象。以下是一个使用mutableStateOf的示例代码: ``` @Composable fun Counter() { var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text(text = "Click count: $count") } } ``` 在这个示例,我们通过调用remember { mutableStateOf(0) }来创建了一个可变状态的变量count,并将其初始值设置为0。每次点击Button时,我们通过更新count的值来实现状态的变化。 remember是Compose的一个函数,用于在组件之间共享和保存状态。这个函数接受一个lambda表达式,在其可以创建和初始化状态变量,并返回这些状态变量作为组件的参数。以下是一个使用remember的示例代码: ``` @Composable fun UserName() { val name = remember { mutableStateOf("") } TextField( value = name.value, onValueChange = { name.value = it }, label = { Text(text = "Enter your name") } ) Button(onClick = { /* 执行一些与用户名相关的操作 */ }) { Text(text = "Submit") } } ``` 在这个示例,我们通过记住一个空的字符串作为初始值来创建了一个mutableStateOf变量name,并将它作为参数传递给了TextField。用户在文本框输入的内容会更新name的值。 ### 回答3: Jetpack Compose 是一种用于构建 Android 用户界面的现代工具包。在 Jetpack Compose ,mutableStateOf 和 REMBER 是两个关键概念。 mutableStateOf 是一个函数,用于创建一个可变的状态。它接受一个初始值作为参数,并返回一个包含状态和状态更新函数的对象。通过调用状态更新函数,我们可以更改状态的值,并触发界面的重新绘制。 以下是一个使用 mutableStateOf 的简单示例: ``` @Composable fun Counter() { val count = mutableStateOf(0) Button(onClick = { count.value++ // 通过修改count的值,触发重新绘制界面 }) { Text(text = "Click me") } Text(text = "Count: ${count.value}") } ``` 在这个示例,我们定义了一个名为 Counter 的 Composable 函数。在函数内部,我们创建了一个名为 count 的可变状态,初始值为 0。接着,我们创建了一个按钮,当用户点击按钮时,通过递增 count 的值来触发界面重新绘制。最后,我们展示了当前 count 值的文本。 REMBER 是另一个在 Jetpack Compose 常用的概念。它是用于在重新绘制时保留组件状态的函数。REMBER 函数接受一个参数,并返回一个 State 的值。在重新绘制时,如果 REMBER 的参数没有改变,那么 Jetpack Compose 会尝试重用之前保存的状态值。 以下是一个使用 REMBER 的简单示例: ``` @Composable fun RememberExample() { val rememberedValue = remember { mutableStateOf(0) } Button(onClick = { rememberedValue.value++ }) { Text(text = "Click me") } Text(text = "Remembered value: ${rememberedValue.value}") } ``` 在这个示例,我们定义了一个名为 RememberExample 的 Composable 函数。在函数内部,我们使用 REMBER 函数创建了一个名为 rememberedValue 的可变状态。如果重新绘制时,RememberExample 函数的参数没有改变,Jetpack Compose 会尝试重用之前保存的 rememberedValue 的值。当用户点击按钮时,我们递增 rememberedValue 的值,并重新绘制界面。最后,我们展示了当前 rememberedValue 值的文本。 通过使用 mutableStateOf 和 REMBER,我们可以轻松地管理状态和保留组件的状态,从而构建出更加动态和交互的用户界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值