返回

Jetpack Compose rememberSaveable(mutableStateOf()) 值丢失?2 种方法解决!

Android

解决 Jetpack Compose 中 rememberSaveable(mutableStateOf()) 的值丢失问题

问题概览

Jetpack Compose 中的 rememberSaveable 函数可用于在设备旋转或导航等配置更改期间保留状态值。然而,对于可变状态对象(如 mutableStateOf()),值丢失是一个常见问题。

问题原因

mutableStateOf() 返回的可变状态对象允许其值在运行时更改。但 rememberSaveable 仅在首次调用时对状态对象进行快照。因此,如果在配置更改后更新了可变状态对象,快照值将保持不变,导致值丢失。

解决方法

方法 1:使用 rememberUpdatedState()

rememberUpdatedState() 函数可以跟踪可变状态对象的更新。它返回一个新的状态对象,该对象在原始状态对象更新时会更新。

例如:

var span by rememberUpdatedState(newValue = mutableStateOf(0L))

现在,每次更新 span 时,rememberUpdatedState() 都会返回一个新的状态对象,从而解决值丢失问题。

方法 2:使用 rememberSaveable()

另一种方法是使用 rememberSaveable() 函数直接存储可变状态对象。此方法仅在状态对象的值在配置更改后确实需要保留时才推荐使用。

例如:

var span by rememberSaveable { mutableStateOf(0L) }

注意: 使用此方法时,确保将 saveStaterestoreState 设置为 true,以在导航时保留和恢复状态。

例子

方法 1:使用 rememberUpdatedState()

@Composable
fun Screen1() {
    var span by rememberUpdatedState(newValue = mutableStateOf(0L))
    
    someOP() {
        span = 2
    }
}

方法 2:使用 rememberSaveable()

@Composable
fun Screen2() {
    var span by rememberSaveable { mutableStateOf(0L) }
    
    someOP() {
        span = 2
    }
}

常见问题解答

1. 为什么 rememberSaveable() 不会自动更新可变状态对象?

因为 rememberSaveable 仅在首次调用时创建状态对象的快照。

2. 什么时候应该使用 rememberUpdatedState(),什么时候应该使用 rememberSaveable()

  • 使用 rememberUpdatedState(),当需要在配置更改后保持可变状态对象的值更新时。
  • 使用 rememberSaveable(),当需要在配置更改后保留可变状态对象的确切值时。

3. rememberSaveable()saveable() 有什么区别?

rememberSaveable() 用于存储状态对象,而 saveable() 用于存储可序列化数据。

4. 如何在导航时保留和恢复 rememberSaveable() 中存储的状态?

通过将 saveStaterestoreState 设置为 true

5. 为什么使用 rememberUpdatedState() 比使用 rememberSaveable() 效率更高?

因为 rememberUpdatedState() 只在原始状态对象更新时创建新的状态对象,而 rememberSaveable() 总是创建新的状态对象。