SavedStateHandle ViewModel не сохраняет состояние при навигации и очистке стекаAndroid

Форум для тех, кто программирует под Android
Ответить
Гость
 SavedStateHandle ViewModel не сохраняет состояние при навигации и очистке стека

Сообщение Гость »

У меня есть приложение для Android с несколькими экранами, управляемое Jetpack Navigation. В моем приложении я использую SavedStateHandle в моей ViewModel, чтобы сохранять определенные состояния при изменениях конфигурации и событиях навигации. В частности, у меня есть сценарий, в котором я перехожу от ScreenFirst к ScreenSecond, а на ScreenSecond я переключаю видимость кнопки на основе значения isBackButtonVisible.
Однако, несмотря на сохранение этого значения в SavedStateHandle, когда я нажимаю кнопку «Назад», чтобы вернуться к ScreenFirst, а затем возвращаюсь к ScreenSecond, видимость кнопки всегда сбрасывается в исходное состояние (false) вместо сохранения ранее установленного значения.
Кроме того, я хочу очистить задний стек при переходе с одного экрана на другой, чтобы обеспечить последовательный поток навигации. Хотя я реализовал popUpTo для очистки обратного стека, похоже, это не влияет на сохранение значения isBackButtonVisible .
Как я могу гарантировать, что SavedStateHandle в моей ViewModel сохраняет состояние между событиями навигации и очисткой обратного стека? Что может быть причиной проблемы с неправильным сохранением состояния?
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi
import androidx.lifecycle.viewmodel.compose.saveable
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import org.koin.androidx.compose.navigation.koinNavViewModel

class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NavigationScreen()
}
}
}

@Composable
fun NavigationScreen(navController: NavHostController = rememberNavController()) {
NavHost(
navController = navController,
startDestination = "ScreenFirst",
route = "parentRoute"
) {

composable("ScreenFirst") {
Button(onClick = {
navController.navigateWithClearStack("ScreenSecond")
}) {
Text(text = "Move to Second Screen")
}
}

composable("ScreenSecond") {

val viewModel: SecondViewModel = koinNavViewModel()

Column(modifier = Modifier.fillMaxSize()) {
Button(onClick = { viewModel.update(true) }) {
Text(text = "Show Back Button")
}

AnimatedVisibility(visible = viewModel.isBackButtonVisible) {
Button(onClick = {
navController.navigateWithClearStack("ScreenFirst")
}) {
Text(text = "Move to Back Screen")
}
}
}
}
}
}

fun NavController.navigateWithClearStack(screenRoute: String) {
this.navigate(screenRoute) {
// Clear the back stack up to the start destination
popUpTo(currentBackStackEntry?.destination?.route ?: return@navigate) {
inclusive = true
}
// Specify the new start destination
launchSingleTop = true
}
}

class SecondViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {

@OptIn(SavedStateHandleSaveableApi::class)
var isBackButtonVisible by savedStateHandle.saveable { mutableStateOf(false) }
private set

fun update(value: Boolean) {
isBackButtonVisible = value
}
}


Подробнее здесь: https://stackoverflow.com/questions/781 ... stack-clea
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»