Flutter - Drawer: показывать существующую страницу, если она существует, а не новый экземпляр
Приложение, которое я разрабатываю, пытается максимально адаптировать возможности для пользователей Android и iOS.
Для этого приложение запускает
CupertinoApp
и
MaterialApp
.
На iOS я использую
CupertinoScaffold
показывая с
BottomNavigationBarItems
. Он работает очень хорошо, как и ожидалось:
- страницы создаются только один раз, когда я впервые нажимаю на вкладку;
- страницы восстанавливаются при возврате к ранее отображаемой вкладке: на одной из моих вкладок есть список, и его положение прокрутки всегда сохраняется, сохраняется.
на Android все по-другому: я использую
Drawer
виджет. Когда я нажимаю на запись, я звоню
Navigator#push
чтобы показать связанную страницу. Однако это будет продолжать добавлять новые экземпляры каждой страницы записи в стек.
Кажется, я не могу вернуться на существующую страницу . По крайней мере, как я могу это сделать с iOS.
Глядя на
Navigator
Я вижу функции, которые, кажется, достигают того, что я ищу:
-
popUntil
=> покажет мой существующий экран, но на просторах всех остальных, которые поэтому принесут жертву ради одной страницы. Столько шума напрасно ... -
pushReplacement
=> покажет новый экземпляр целевой страницы и уничтожит текущий. Не желательно.
Что мне не хватает? Как я могу добиться этого
CupertinoTabBar
вроде умеет делать?
1 ответ
Что ж, я решил свою проблему, выбрав другое направление.
Проще говоря, я не думаю, что есть способ достичь того, чего я хочу.
Решение, которое я нашел, было: сохранять состояние виджетов с помощью нижней панели навигации во Flutter.
В этом руководстве предлагается использовать элемент, который отображает только одного дочернего элемента одновременно, сохраняя его состояние.
Вот как мне удалось заставить его работать:
- Создайте свой
MaterialApp
- Установите его
home
быть настраиваемым виджетом с отслеживанием состояния, называемым - Это создает
Scaffold
:- с символом и его заголовком (заголовок активной страницы);
- с
drawer
и его аргументы (подробнее об этом позже) - и
body
это так называемое чудесное:- установить его
children
быть списком страниц / виджетов, те же страницы, доступные в ящике - набор
index
быть собственностью вашего
- установить его
- и с функцией, которая будет запускаться, когда пользователь выбирает страницу для перехода, и в этом случае обычный вызов
setState
происходит внутри которого вы можете обновить свойство, а также_selectedPageIndex
собственности`.
- В
Drawer
:- принимает два параметра:
- индекс текущей активной страницы (по умолчанию 0 при запуске приложения)
- а
Function
с заголовком и индексом целевой страницы
- должен указать столько же записей (обычно
ListTile
) как страницы, которые вы объявили в отображаемом в. - после щелчка по записи он вызывает вышеупомянутую функцию и передает индекс выбранной записи, а также соответствующий заголовок страницы.
- принимает два параметра:
В итоге что происходит:
- Пользователь открывает ящик.
- Пользователь выбирает новое место назначения (скажем: запись №3).
-
MaterialHomePage
получает уведомление (через обратный вызов) о выборе пользователя, который запускаетsetStage
это будет одновременно:- обновить текущую страницу благодаря
IndexedStack
с участиемindex = 3
- и обновить его
AppBar
название
- обновить текущую страницу благодаря
и вуаля, готово : каждая страница сохраняется, без потери состояния и плавной навигации.
NB: если пользователь использует функцию кнопки "Назад" на Android, на этом этапе он закроет приложение, так как
Navigator
стек пуст. Возможно, есть способ прослушать такое событие, если вы хотите по умолчанию использовать первую запись / страницу (отображаемую при запуске), если пользователь находился на другой странице.
NB2: Мне также интересно, есть ли способ анимировать переходы между страницами.
PS: Сообщите мне, являются ли ответы хорошим решением, и в этом случае я проверю его. Или если вы найдете способ добиться этого.