一、Saver 是干嘛的?(必须Compose中使用)
Saver = 状态保存 + 恢复工具 作用:屏幕旋转、切换暗黑模式、窗口大小变化 → 让你的状态不丢失!
比如:
- 输入框文字不消失
- 轮播图当前页不重置
- 自定义状态(页码、播放进度、选中项)不丢失
二、核心原理(超简单)
Compose 界面重建时:
- save :把你要保存的少量数据存起来
- restore :用存好的数据重新构建状态
三、最简单的标准写法(背会这个就够)
kotlin
ini
val 自定义Saver = Saver<你的状态类, 保存的数据类型>(
save = { 状态对象 ->
// 要保存什么?返回要存的值
状态对象.要保存的属性
},
restore = { 保存的值 ->
// 如何恢复?返回新的状态对象
你的状态类(保存的值)
}
)
实战例子:
kotlin
class MainActivity : ComponentActivity() {
companion object{
val CommonSaver = Saver<SimpleState, Int>(
save = {
Log.d("lyy", "----------------Saving state: ${it.page}")
it.page
},
restore = {
Log.d("lyy", "------------------restore state: ${it}")
SimpleState(it)
}
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyDemo4Theme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
rememberPageState()
}
}
}
}
}
@Composable
fun rememberPageState(): SimpleState {
val rememberSaver = rememberSaveable(
saver = CommonSaver // 一定要绑定 saver!
) {
SimpleState(page = 668)
}
return rememberSaver
}
data class SimpleState(val page: Int)
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
rememberPageState()
}
四、我用你刚才的 Banner 例子讲透
kotlin
kotlin
data class BannerState(
val initialPage: Int = 0
)
定义 Saver
kotlin
ini
val BannerSaver: Saver<BannerState, Int> = Saver(
// 保存:把当前页码存起来
save = { currentState ->
currentState.initialPage // 只存页码(Int)
},
// 恢复:用存好的页码重建 BannerState
restore = { savedPage ->
BannerState(initialPage = savedPage)
}
)
如何使用?
配合 rememberSaveable 使用:
kotlin
ini
val bannerState = rememberSaveable(
saver = BannerSaver
) {
BannerState(initialPage = 0)
}
五、为什么要用 rememberSaveable?
remember:旋转屏幕就丢失rememberSaveable + Saver:旋转屏幕不丢失
系统自动帮你:
- 重建时 save
- 恢复时 restore
六、最常见的 3 种 Saver 实战
1. 保存简单状态(数字、布尔、字符串)
你刚才的 Banner 就是这种。
kotlin
kotlin
data class SimpleState(val page: Int)
val SimpleSaver = Saver<SimpleState, Int>(
save = { it.page },
restore = { SimpleState(it) }
)
2. 保存多个字段(最常用)
kotlin
ini
data class UserState(
val name: String,
val age: Int,
val isLogin: Boolean
)
val UserSaver = Saver<UserState, Bundle>(
save = { state ->
bundleOf(
"name" to state.name,
"age" to state.age,
"isLogin" to state.isLogin
)
},
restore = { bundle ->
UserState(
name = bundle.getString("name") ?: "",
age = bundle.getInt("age"),
isLogin = bundle.getBoolean("isLogin")
)
}
)
3. 系统自带 Saver(不用自己写)
- String
- Int
- Boolean
- Float
- List
- Bundle
这些系统自动保存,直接用:
kotlin
csharp
var name by rememberSaveable { mutableStateOf("") }
七、Saver 什么时候必须用?
只要你有自定义数据类,且希望:
- 屏幕旋转不丢失
- 状态不重置
就必须写 Saver
八、一句话总结(最核心)
- Saver = 告诉系统如何保存 & 恢复你的自定义状态
- save = 存什么
- restore = 怎么恢复
- rememberSaveable + Saver = 状态永不丢失
九、你那一段代码最终解释(最精简版)
kotlin
scss
val Saver: Saver<BannerState, *> = Saver(
save = { it.initialPage }, // 保存当前页码
restore = { BannerState(it) } // 用页码恢复状态
)
作用:旋转屏幕时,Banner 保持当前页,不回到第 0 页。