【发布时间】:2021-08-01 19:40:31
【问题描述】:
我在 Jetpack Compose 与 Navigation 结合时遇到了一个奇怪的行为:如果您在一些可组合的导航中使用 rememberSaveable,则状态不会按承诺保存(例如,旋转后会丢失)。这是一个简单的例子:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.MaterialTheme
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
MyScreen()
}
}
}
}
@Composable
fun MyScreen() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "xyz") {
composable("xyz") {
var value by rememberSaveable { mutableStateOf("") }
TextField(value = value, onValueChange = { value = it })
}
}
}
上面的代码生成一个可以输入的文本字段。一旦旋转屏幕,输入的文本就会丢失,即使值应该由 rememberSaveable 保存。
调查了一下,我注意到了以下几点:
-
问题出在 NavHost 上。如果将定义变量“value”的行移到“MyScreen()”的顶部(在 NavHost 之外),那么一切都会按预期进行。
-
真正的问题似乎是可组合变量“currentCompositeKeyHash”在 NavHost 内的配置更改后没有保留。该变量用作 savedInstanceBundle 的键,以通过 rememberSaveable 检索保存的值,从而丢失状态。特别是,如果在 rememberSaveable 中明确指定一个键,那么一切都会按预期工作。
这是一个错误还是我误解了什么?
【问题讨论】:
-
撰写导航仍处于 alpha 阶段,因此可能是一个错误。在此处创建问题:issuetracker.google.com/issues/…
-
我觉得很不错
-
我刚刚注意到今天有人对此提出了问题:issuetracker.google.com/issues/195242927
-
显然,该问题已在 2.4.0-alpha07 版本内部修复,希望很快会发布。 issuetracker.google.com/issues/195141957#comment4
-
顺便说一句,2.4.0-alpha07 已经发布。
标签: android-jetpack-compose android-architecture-navigation jetpack-compose-navigation