Compose中 Saver的使用:

一、Saver 是干嘛的?(必须Compose中使用)

Saver = 状态保存 + 恢复工具 作用:屏幕旋转、切换暗黑模式、窗口大小变化 → 让你的状态不丢失!

比如:

  • 输入框文字不消失
  • 轮播图当前页不重置
  • 自定义状态(页码、播放进度、选中项)不丢失

二、核心原理(超简单)

Compose 界面重建时:

  1. save :把你要保存的少量数据存起来
  2. 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()
}

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 页。

相关推荐
传奇开心果编程1 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
天空之城--4 天前
Android一周动态:Android 18首次官宣、Compose Material3 1.4转正(5趋势+5资讯)
android·人工智能·flutter·架构·android jetpack
传奇开心果编程5 天前
【现代声明式UI学与练】第1课 从命令式UI到声明式UI
学习·flutter·ui·swiftui·react·android jetpack
传奇开心果编程8 天前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
传奇开心果编程9 天前
【Jetpack Compose进阶学与练】第14课:系列收尾复习总结;Compose项目常见坑点汇总;学习路线与后续学习方向
android·学习·ui·kotlin·android jetpack
hai_android9 天前
子 View 被压小时,如何向父容器"告状"?——MEASURED_STATE_TOO_SMALL 向上传递机制
android·kotlin·android jetpack
alexhilton10 天前
生命周期感知的多模块启动模式
android·kotlin·android jetpack
hai_android10 天前
RecyclerView 缓存机制详解
android·kotlin·android jetpack