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

相关推荐
撩得Android一次心动6 天前
Android Room 数据库详解【源码篇】
android·数据库·android jetpack·room
我命由我123456 天前
Kotlin 开发 - 双冒号操作符(引用顶层函数、引用成员函数、引用构造函数、引用属性、引用类)
android·java·开发语言·kotlin·android studio·android jetpack·android-studio
我命由我123456 天前
Kotlin 开发 - sealed 关键字
android·java-ee·kotlin·android studio·android jetpack·android-studio·android runtime
我命由我123457 天前
Android 开发问题:Raw use of parameterized class ‘Class‘
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
alexhilton10 天前
Compose中的CameraX二维码扫描器
android·kotlin·android jetpack
QING61811 天前
Kotlin之【init】—— 新手须知
android·kotlin·android jetpack
我命由我1234511 天前
Android 开发问题:Unresolved reference: kapt
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
阿巴斯甜12 天前
MultiDex的使用:
android jetpack
阿巴斯甜12 天前
Media3 的使用
android jetpack