Jetpack Compose + Navigation: RememberSaveable теряет состояние при повороте
Я столкнулся со странным поведением Jetpack Compose в сочетании с навигацией: если вы используете 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. Если переместить строку, определяющую переменную «значение», в начало «MyScreen ()» (вне NavHost), тогда все будет работать, как задумано.
Реальная проблема, похоже, заключается в том, что составная переменная currentCompositeKeyHash не сохраняется после изменений конфигурации внутри NavHost. Эта переменная используется в качестве ключа для savedInstanceBundle для извлечения сохраненного значения с помощью RememberSaveable, таким образом состояние теряется. В частности, если кто-то явно указывает ключ в RememberSaveable, все работает, как ожидалось.
Это ошибка или я что-то не понимаю?
2 ответа
Это известная проблема с версией
2.4.0-alpha05
и
2.4.0-alpha06
из
androidx.navigation:navigation-compose
. Текущее решение - перейти на
2.4.0-alpha04
:
implementation "androidx.navigation:navigation-compose:2.4.0-alpha04"
Согласно системе отслеживания проблем , проблема исправлена в версии
2.4.0-alpha07
, который, надеюсь, скоро будет выпущен.
Использовать
androidx.navigation:navigation-compose:2.4.0-alpha04