Я хотел бы иметь разные анимации навигации для одной и той же страницы, но для разных сценариев навигации. Например.
Практический сценарий, например. page1 — это одна из страниц из BottomNavigationBar. page5 — это страница для обновления некоторых свойств со страницы page1. Я хочу подчеркнуть, используя различные анимации навигации, что страница 1 является основной, а страница 5 — второстепенной.
Итак, я столкнулся со следующей проблемой. Я не могу найти надежное решение для получения имен «предыдущих» и «следующих» страниц. Приведенный ниже блок кода представляет собой EnterTransition для страницы 1 с оператором условия для поддержки различных анимаций на основе имени предыдущей страницы.
enterTransition = { //enterTransition for page1
when("previousPageName") {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}
чтобы получить имя предыдущей страницы, по-видимому, лучше всего использовать NavigationController, поэтому приведенный выше пример можно переписать.
enterTransition = { //enterTransition for page1
when(**navController.previousBackStackEntry!!.destination.route**) {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}
Я ожидал найти там название предыдущей страницы в любое время. Но на практике, в случае, когда навигация осуществляется с помощью NavigationController.popUpBackStack(), например. нажав кнопку «вернуться назад». Он удаляет/разбивает navController.previousBackStackEntry и в результате содержит страницу, которую я не ожидаю, например. "страница3". И я могу понять такое поведение, оно работает с BackStack, но если так, то я понятия не имею, как управлять разными анимациями между разными страницами на основе состояния графа навигации. Одним из возможных решений может быть использование/управление переменной для хранения предыдущей страницы, но это последнее, что я буду использовать для достижения своих целей. Было бы неплохо найти более элегантное решение.
Итак, у меня есть пара вопросов:
popUpBackStack()
илиnavController.navigate("page1") {
popUpTo(
"page5"
) { inclusive = true }
}
Заранее благодарю за помощь.
Пытался получить предыдущую страницу из NavigationController.previousBackStackEntry, но без необходимого результата.
Как поясняется в блоге Анимации в навигационном компоновке, каждая лямбда-переход имеет формат:
enterTransition: (
AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition?
)? = null,
Что, как поясняет:
Эта лямбда использует AnimatedContentScope, чтобы предоставить вам
NavBackStackEntry
того, откуда вы пришли (initialState
) и куда вы собираетесь (targetState
). Например, дляenterTransition
входящим пунктом назначения являетсяtargetState
— тот, к которому вы применяетеenterTransition
.
Это позволяет вам писать код, например:
enterTransition = {
// initialState is the screen you are coming from (the one leaving)
// targetState is the screen you are going to (the one entering)
when(initialState.destination.route) {
"page1" -> fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
"page2" -> fadeIn() + slideInHorizontally()
else -> fadeIn()
}
}
Спасибо @ianhanniballake, это работает! Пропустил эту часть(