При использовании новой навигации Compose, которая по умолчанию включает анимацию в NavHost, я столкнулся с несколькими проблемами с navController.popBackStack(). (Редактирование 2: навигационная версия 2.8.0-beta03)
2 основных вопроса были:
Мне удалось решить обе проблемы, проверив жизненный цикл навигации перед вызовом popBackStack() с помощью приведенного ниже кода:
if (navController.currentBackStackEntry?.lifecycle?.currentState == Lifecycle.State.RESUMED) {
navController.popBackStack()
}
Теперь все работает, за исключением того, что теперь я не могу вызвать popBackStack() до завершения анимации, что приводит к некоторому неуклюжему поведению, когда пользователи не могут вернуться назад в течение 700-1000 мс из-за того, что жизненный цикл не находится в состоянии ВОЗОБНОВЛЕНИЕ сразу после отображения экрана (из-за анимация кроссфейда по умолчанию длительностью около 700 мс по умолчанию)
Я проверил, как ведет себя системная кнопка «Назад» в этом сценарии, и я никогда не сталкивался ни с одной из двух проблем, перечисленных выше, более того, я могу вернуться назад сразу после перехода вперед, без необходимости ждать ВОЗОБНОВЛЕНИЯ жизненного цикла без каких-либо проблем, перечисленных выше. .
Я проверил реализацию NavHost, и единственное, что они делают, это реализуют BackHandler, в котором есть navController.popBackStack(), поэтому мне интересно, является ли исправление, которое я сделал, правильным способом извлечения стека.
Я хотел бы, чтобы мои кнопки «Назад» вели себя так же, как системные нажатия, без удаления анимации навигации по умолчанию.
Любая информация по этой теме приветствуется, так как в официальной документации я не смог найти ничего полезного о том, как решить эту проблему.
Редактировать 1: Чтобы дать больше контекста второй проблеме, поскольку она более серьезная, я привожу ее изображение ниже:
Мой задний стек:
ScreenA -> ScreenB -> ScreenC -> ScreenD
тогда я сделаю navController.popBackStack()
Тогда мой задний стек становится:
ScreenA -> ScreenB -> ScreenC (-> ScreenD still partially visible)
Обычно экран D белый с заголовком «Экран D» вверху по центру, а экран C желтый с заголовком «Экран C» посередине. При вызове navController.popBackStack() до завершения анимации плавного перехода от C к D экран D выталкивается из заднего стека, но остается на экране и из-за альфа-перехода он перекрывается с фактическим текущим экраном, то есть экраном C.
Уже сделал, это решает первую проблему, но не решает вторую.





Мне хотелось бы знать, какую версию создания навигации вы используете. Если вы используете новую версию создания типовой навигации: 2.8.0-beta03 или 2.8.0-beta01 или версию, которая 2.8.0-alpha08 вводит Safe Args в Navigation Compose, в этой версии есть какая-то странная ошибка в самой библиотеке, особенно в выталкивание стека.
Если мы используем navController.popBackStack или navController.navigateUp для возврата к предыдущему экрану, он иногда возвращается, а иногда не просто зависает.
Чтобы решить эту проблему, перейдите на стабильную версию создания навигации, которая на данный момент 2.7.7.
Я уже сообщал об этой ошибке в трекере ошибок, кстати, не только я, но и многие другие. См.: https://issuetracker.google.com/issues/347114499
Я действительно был в версии 2.8.0-beta03, тестируя новую безопасную навигацию по типам, я проверил журнал изменений и, кроме навигации по сохранению типов и некоторых изменений безопасных аргументов, я не увидел ничего, связанного с самим обратным стеком, поэтому я не думал, что новая версия оказало на это влияние... я откатился на 2.7.7, и все работает как задумано. думаю, мне придется немного подождать с типобезопасной навигацией :D спасибо за предупреждение об ошибках с обратным стеком в версиях 2.8.0+
Попробуйте
navController.navigateUp()?