Восстановить состояние предыдущего компонуемого объекта при переходе назадAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Восстановить состояние предыдущего компонуемого объекта при переходе назад

Сообщение Anonymous »

У меня возникли проблемы с состоянием и навигацией в Compose.
У меня есть экран A с панелью поиска. При нажатии на результат поиска происходит переход к подробному экрану, а когда я возвращаюсь назад, экран A возвращается в исходное состояние (нет результатов, нет ввода в строку поиска и т. д.). Есть ли способ сохранить состояние экрана A при переходе обратно с подробного экрана?
Я пробовал использовать saveState и restoreState, но безуспешно. Я не знаю, это конфигурация навигации или что-то еще...
Смотрите видео проблемы -> https://youtube.com/shorts/j8qRdUu5dNI?feature=share
Это мой NavHost:
SharedTransitionLayout {
NavHost(
modifier = Modifier.fillMaxSize().padding(padding).background(MaterialTheme.colorScheme.background),
navController = navController,
startDestination = CardSearchRoute
) {

composable {
val viewModel = koinViewModel()
val state by viewModel.state.collectAsStateWithLifecycle()
CardSearchScreen(
state = state,
onEvent = viewModel::onEvent,
animatedVisibilityScope = this,
onCardClicked = {
navController.navigate(CardDetailRoute(cardID = it.id))
}
)

}

composable { backStackEntry ->
val cardID = backStackEntry.toRoute().cardID
val viewmodel = koinViewModel(parameters = { parametersOf(cardID) })
val state by viewmodel.state.collectAsStateWithLifecycle()
CardDetailScreen(
state = state, animatedVisibilityScope = this,
onEvent = {}
)
}

composable {
todoScreen("Collection")
}

composable {
todoScreen("Scanning")
}
}
}

Вот код для моих экранов и модели представления:
Экран поиска:
@OptIn(ExperimentalSharedTransitionApi::class, ExperimentalMaterial3Api::class)
@Composable
fun SharedTransitionScope.CardSearchScreen(
state: UIState,
onEvent: (UIEvent) -> Unit,
onCardClicked: (Card) -> Unit,
animatedVisibilityScope: AnimatedVisibilityScope
) {

LaunchedEffect(Unit) {
onEvent(UIEvent.OnSearchBarTextChanged(""))
}

Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {

SearchBar(
windowInsets = WindowInsets(top = 0),
modifier = Modifier.padding(16.dp).fillMaxWidth(),
shape = RoundedCornerShape(corner = CornerSize(8.dp)),
inputField = {
SearchBarDefaults.InputField(
query = state.searchBarText ?: "",
onQueryChange = {
onEvent(UIEvent.OnSearchBarTextChanged(it))
},
onSearch = { },
expanded = false,
onExpandedChange = { },
placeholder = { Text("Search by name") },
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.White,
cursorColor = Color.White,
focusedLabelColor = Color.White, unfocusedPlaceholderColor = Color.White.copy(alpha = 0.5f), focusedPlaceholderColor = Color.White.copy(alpha = 0.5f)
),
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
)
},
expanded = false,
onExpandedChange = { },
) { }

Box(
modifier = Modifier.fillMaxHeight()
) {
if (state.isLoading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center)
)
} else {
val cards = state.foundCards.map { it }.toSet()
LazyColumn (
horizontalAlignment = Alignment.CenterHorizontally
) {
item{
CardCarrousel(
title = "LEADERS",
cards = cards,
type = CardType.LEADER,
onCardClicked = onCardClicked,
animatedVisibilityScope = animatedVisibilityScope
)
}

item{
CardCarrousel(
title = "BASES",
cards = cards,
type = CardType.BASE,
onCardClicked = onCardClicked,
animatedVisibilityScope = animatedVisibilityScope

)
}

item{
CardCarrousel(
title = "UNITS",
cards = cards,
type = CardType.UNIT,
onCardClicked = onCardClicked,
animatedVisibilityScope = animatedVisibilityScope

)
}

item{
CardCarrousel(
title = "EVENTS",
cards = cards,
type = CardType.EVENT,
onCardClicked = onCardClicked,
animatedVisibilityScope = animatedVisibilityScope

)
}

item{
CardCarrousel(
title = "UPGRADES",
cards = cards,
type = CardType.UPGRADE,
onCardClicked = onCardClicked,
animatedVisibilityScope = animatedVisibilityScope

)
}
}

}
}

}

}


Модель просмотра:
class CardSearchViewModel(
private val searchCardUseCase: SearchCardUseCase
) : ViewModel() {

private val _state = MutableStateFlow(UIState())
val state = _state.asStateFlow()

fun onEvent(event: UIEvent) {
when (event) {
is UIEvent.OnSearchBarTextChanged ->{
_state.update {
it.copy(
searchBarText = event.text
)
}
searchJob?.cancel()
search()
}

}
}

var searchJob: Job? = null

private fun search() {
searchJob = viewModelScope.launch(Dispatchers.IO) {
searchCardUseCase.invoke(_state.value.searchBarText!!).collect { result ->
result.onLoading { _, _ ->
_state.update {
it.copy(
isLoading = true,
foundCards = emptySet()
)
}
}.onSuccess { foundCards ->
_state.update {
it.copy(
isLoading = false,
foundCards = foundCards.sortedBy { it.name }.toSet()
)
}
}.onFailure {
_state.update {
it.copy(
isLoading = false
)
}
}
}
}
}

}

data class UIState(
val searchBarText: String? = null,
val isLoading: Boolean = false,
val foundCards: Set = emptySet(),
val sortType: SortType = SortType.NAME
)
sealed class UIEvent {
data class OnSearchBarTextChanged(val text: String) : UIEvent()
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... ating-back
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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