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