#android #kotlin #android-jetpack-compose #android-jetpack-navigation
Вопрос:
Я хочу, чтобы навигация выглядела так:
-У меня есть три экрана: «Вход», «Регистрация» и «Восстановление учетной записи».;
-с каждого экрана я могу перейти на любой другой;
-когда я перехожу с экрана «Вход» на «Регистрация», а затем возвращаюсь к «Входу» (нажав кнопку «Перейти к входу»), я хочу, чтобы у меня был тот же экран, что и в начале, а не новый.
Теперь каждый раз, когда я возвращаюсь в раздел «Вход», я получаю новый экран 🙁
Мой навигатор:
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Screens.Login.route) {
composable(route = Screens.Recovery.route) {
RecoveryScreen(navController = navController)
}
composable(route = Screens.Login.route) {
LoginScreen(navController = navController)
}
composable(route = Screens.Registration.route) {
RegistrationScreen(navController = navController)
}
}
Укажи мне, в какую сторону копать?
Ответ №1:
Откуда вы знаете, что это новый экран? Позвольте мне угадать, вы, должно быть, смотрите на какое-то состояние экрана, например, заполненные текстовые поля будут пустыми, прокручиваемые списки будут сброшены, флажки будут сброшены или что-то в этом роде. Вы видите, что не имеет значения, вызываете ли вы материал из хранилища. Дело в том, что в тот момент, когда композитный файл больше не отображается на экране, он уничтожается, возвращая все состояние к значениям по умолчанию. То есть он всегда будет перекомпонован по запросу навигации. Что вам здесь нужно, так это сохранить все это состояние внутри модели представления. Затем обратитесь к состоянию из самой модели представления. Создайте переменные состояния в модели представления со значениями по умолчанию, а затем всегда ссылайтесь на саму модель представления. Таким образом, при повторной компоновке данные будут извлечены из виртуальной машины, и это все равно будут правильные данные, так как виртуальная машина не уничтожена.
Комментарии:
1. Да, ты прав. Но поскольку я использую Compose, мне не нужно использовать какие-либо фрагменты и несколько действий, так как же мне сохранить экземпляры виртуальной машины? Сброс всех полей LoginVM, RegistrationVM и RecoveryVM, когда пользователь авторизован, кажется не лучшим решением.
2. Ты должен. Вот как это делается. В противном случае вам нужно будет вручную уничтожить модели представлений, а затем при необходимости создать их заново, но почему бы просто не создать простой метод в каждой из виртуальных машин для сброса всех значений сразу?
3. Этот подход заставляет меня вызывать метод сброса каждой виртуальной машины (в этом случае 3 виртуальных машины) для каждого из этих экранов, это просто простой пример. Но что, если у меня есть десять разных экранов в задней стопке, и я хочу выйти из системы, в этом случае мне нужно сбросить все виртуальные машины. Я думаю, что это решение, подверженное ошибкам.
4. Я не думаю, что это оптимальное решение, я знал, что мне нужно хранить данные в моих виртуальных машинах, но при переходе с вкладки на другую вкладку содержимое создает эффект мерцания, анимация запускается снова, прокрутка потеряла свое значение, я не думаю, что это хорошо для пользователя.