Compose中 Saver的使用:

26 阅读2分钟

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

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

比如:

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

二、核心原理(超简单)

Compose 界面重建时:

  1. save:把你要保存的少量数据存起来
  2. restore:用存好的数据重新构建状态

三、最简单的标准写法(背会这个就够)

kotlin

val 自定义Saver = Saver<你的状态类, 保存的数据类型>(
    save = { 状态对象 ->
        // 要保存什么?返回要存的值
        状态对象.要保存的属性
    },
    restore = { 保存的值 ->
        // 如何恢复?返回新的状态对象
        你的状态类(保存的值)
    }
)

实战例子:


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

data class BannerState(
    val initialPage: Int = 0
)

定义 Saver

kotlin

val BannerSaver: Saver<BannerState, Int> = Saver(
    // 保存:把当前页码存起来
    save = { currentState ->
        currentState.initialPage  // 只存页码(Int)
    },
    // 恢复:用存好的页码重建 BannerState
    restore = { savedPage ->
        BannerState(initialPage = savedPage)
    }
)

如何使用?

配合 rememberSaveable 使用:

kotlin

val bannerState = rememberSaveable(
    saver = BannerSaver
) {
    BannerState(initialPage = 0)
}

五、为什么要用 rememberSaveable?

  • remember旋转屏幕就丢失
  • rememberSaveable + Saver旋转屏幕不丢失

系统自动帮你:

  • 重建时 save
  • 恢复时 restore

六、最常见的 3 种 Saver 实战

1. 保存简单状态(数字、布尔、字符串)

你刚才的 Banner 就是这种。

kotlin

data class SimpleState(val page: Int)

val SimpleSaver = Saver<SimpleState, Int>(
    save = { it.page },
    restore = { SimpleState(it) }
)

2. 保存多个字段(最常用)

kotlin

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

var name by rememberSaveable { mutableStateOf("") }

七、Saver 什么时候必须用?

只要你有自定义数据类,且希望:

  • 屏幕旋转不丢失
  • 状态不重置

就必须写 Saver


八、一句话总结(最核心)

  • Saver = 告诉系统如何保存 & 恢复你的自定义状态
  • save = 存什么
  • restore = 怎么恢复
  • rememberSaveable + Saver = 状态永不丢失

九、你那一段代码最终解释(最精简版)

kotlin

val Saver: Saver<BannerState, *> = Saver(
    save = { it.initialPage },        // 保存当前页码
    restore = { BannerState(it) }    // 用页码恢复状态
)

作用:旋转屏幕时,Banner 保持当前页,不回到第 0 页。