Flutter - Drawer: показывать существующую страницу, если она существует, а не новый экземпляр

Приложение, которое я разрабатываю, пытается максимально адаптировать возможности для пользователей Android и iOS.

Для этого приложение запускает CupertinoApp и MaterialApp.

На iOS я использую CupertinoScaffold показывая с BottomNavigationBarItems. Он работает очень хорошо, как и ожидалось:

  • страницы создаются только один раз, когда я впервые нажимаю на вкладку;
  • страницы восстанавливаются при возврате к ранее отображаемой вкладке: на одной из моих вкладок есть список, и его положение прокрутки всегда сохраняется, сохраняется.

на Android все по-другому: я использую Drawerвиджет. Когда я нажимаю на запись, я звоню Navigator#pushчтобы показать связанную страницу. Однако это будет продолжать добавлять новые экземпляры каждой страницы записи в стек.

Кажется, я не могу вернуться на существующую страницу . По крайней мере, как я могу это сделать с iOS.

Глядя на Navigator Я вижу функции, которые, кажется, достигают того, что я ищу:

  • popUntil=> покажет мой существующий экран, но на просторах всех остальных, которые поэтому принесут жертву ради одной страницы. Столько шума напрасно ...
  • pushReplacement=> покажет новый экземпляр целевой страницы и уничтожит текущий. Не желательно.

Что мне не хватает? Как я могу добиться этого CupertinoTabBar вроде умеет делать?

1 ответ

Что ж, я решил свою проблему, выбрав другое направление.

Проще говоря, я не думаю, что есть способ достичь того, чего я хочу.

Решение, которое я нашел, было: сохранять состояние виджетов с помощью нижней панели навигации во Flutter.

В этом руководстве предлагается использовать элемент, который отображает только одного дочернего элемента одновременно, сохраняя его состояние.

Вот как мне удалось заставить его работать:

  1. Создайте свой MaterialApp
  2. Установите его home быть настраиваемым виджетом с отслеживанием состояния, называемым
  3. Это создает Scaffold:
    • с символом и его заголовком (заголовок активной страницы);
    • с drawer и его аргументы (подробнее об этом позже)
    • и body это так называемое чудесное:
      • установить его children быть списком страниц / виджетов, те же страницы, доступные в ящике
      • набор index быть собственностью вашего
    • и с функцией, которая будет запускаться, когда пользователь выбирает страницу для перехода, и в этом случае обычный вызов setState происходит внутри которого вы можете обновить свойство, а также _selectedPageIndexсобственности`.
  4. В Drawer:
    • принимает два параметра:
      • индекс текущей активной страницы (по умолчанию 0 при запуске приложения)
      • а Function с заголовком и индексом целевой страницы
    • должен указать столько же записей (обычно ListTile) как страницы, которые вы объявили в отображаемом в.
    • после щелчка по записи он вызывает вышеупомянутую функцию и передает индекс выбранной записи, а также соответствующий заголовок страницы.

В итоге что происходит:

  1. Пользователь открывает ящик.
  2. Пользователь выбирает новое место назначения (скажем: запись №3).
  3. MaterialHomePage получает уведомление (через обратный вызов) о выборе пользователя, который запускает setStage это будет одновременно:
    • обновить текущую страницу благодаря IndexedStack с участием index = 3
    • и обновить его AppBarназвание

и вуаля, готово : каждая страница сохраняется, без потери состояния и плавной навигации.

NB: если пользователь использует функцию кнопки "Назад" на Android, на этом этапе он закроет приложение, так как Navigatorстек пуст. Возможно, есть способ прослушать такое событие, если вы хотите по умолчанию использовать первую запись / страницу (отображаемую при запуске), если пользователь находился на другой странице.

NB2: Мне также интересно, есть ли способ анимировать переходы между страницами.

PS: Сообщите мне, являются ли ответы хорошим решением, и в этом случае я проверю его. Или если вы найдете способ добиться этого.

Другие вопросы по тегам