Составьте перейдите к экрану, который уже находится в фоновом режиме

#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. Я не думаю, что это оптимальное решение, я знал, что мне нужно хранить данные в моих виртуальных машинах, но при переходе с вкладки на другую вкладку содержимое создает эффект мерцания, анимация запускается снова, прокрутка потеряла свое значение, я не думаю, что это хорошо для пользователя.