How To - Flutter Drawer с постоянными дочерними экранами - PullRequest
0 голосов
/ 24 октября 2018

Я новичок во Flutter и пытаюсь выяснить, как добиться чего-то, что я сделал с веб-программированием, а именно, иметь приложение, имеющее несколько «областей», которые могут быть «живыми / текущими» одновременно,Представьте себе приложение, которое имеет 4 «области».Каждая из 4 областей имеет начальный экран, который обычно представляет собой список элементов в этой области.Пользователь может просмотреть детали элемента списка или создать новый элемент списка, используя дополнительный «дочерний» экран для этой области.Каждый из 4 «областей» экранов также включает выдвижной ящик для переключения «текущего вида» на определенную область.Идея такова: пользователь может перейти в область, прокрутить список, отфильтровать список и т. Д. Затем он может попросить ящик перейти в другую область, где он может выполнить аналогичные действия на этом экране.Затем они должны иметь возможность использовать ящик для [повторного] перехода в первую область или в любую другую область, которую они хотят, и, когда они туда попадают, «содержимое» (данные) этого экрана должно быть точно таким же, как оно.было до того, как они покинули этот экран.Обратите внимание, что если они «просверлили» элемент списка или создали новый элемент, у них нет доступа к «блоку области» и они могут только «вернуться» к экрану списка этой области.

ВВ веб-программировании каждая «область» была бы элементом div, и все они «жили бы» на одной странице.Элемент ящика просто скрывал и отображал каждый элемент div, как этого хотел пользователь, при этом каждый из них оставался «нетронутым», пока скрыт.

Итак, вопрос в том, как добиться чего-то подобного в Flutter?Я постепенно начинаю понимать, что такое «дерево виджетов», но, поскольку «экраны» (которые на самом деле являются просто виджетами) «проталкиваются» в дерево, что происходит с экраном, который в данный момент отображается?Я понимаю стек навигации, но что происходит с предыдущим экраном, его виджетами и данными (памятью)?Они «стираются» с дерева?Из предыдущих вопросов, которые я видел, я думаю, что ответ «да».После того, как экран «оттолкнут» снова «выдвигается», он начинает свою жизнь заново, то есть он должен получать данные, прокручивать их, фильтровать, отображать и т. Д. Снова и снова.

Полагаю, мне интересно то, может ли приложение иметь несколько «областей» (экранов) в памяти, в дереве, в одно и то же время, но только «видимый» одновременно, и каждый со своим«дочерняя навигация».Я уверен, что подхожу к вещам «неправильным» образом, но каждая система инструментов / программирования, кажется, подходит к этому вопросу по-своему, и я просто не уверен, как это сделать с Flutter.Я понимаю, что могу хранить все «данные» начальной страницы каждой области в памяти (на уровне приложения) и, таким образом, перестроить каждую область из этих данных (не переходя в базу данных).Я также слышал, как некоторые люди обсуждают «линейную навигацию» (в отличие от иерархической?), Но мало что знают об этом.

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 24 октября 2018

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

(После того, как вы нажали на страницу сведений, вы можете нажать только кнопку «Назад», ящик будет доступен только в списках и других страницах верхнего уровня).

Сами списки можно сортировать, paginate, может фильтровать и быстрый поиск.Каждый список сохраняет свое состояние в сеансе, который основан на шаблоне Inherited Widget.Я основал свой класс Session на этом посте:

Флаттер: Как правильно использовать Inherited Widget?

Если вы хотите перейти в Список A, сортируйте столбец, используя ящик, чтобы перейти к списку B, а затем нажать назад, чтобы вернуться к списку A., список будет отображаться в том же состоянии, в котором вы его оставили.

Если бы вы должны были перейти к списку A, отсортируйтеколонке, использовали ящик для перехода к списку B, а затем снова использовали ящик для перехода к списку A. Список будет отображаться в том же состоянии, в котором вы его оставили.

Разница между этими двумя сценариями заключается в том, чтоСтек навигации выглядит так.В первом случае стек представляет собой просто список А. Во втором случае стек представляет собой список А, список В, список А.

Если вы выбрали второй сценарий, внесите изменения в список А изатем дважды вставьте стек (нажав кнопку «назад»), список A в нижней части стека на самом деле выглядит как список A, который вы изменили выше в стеке.

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

class Session extends StatefulWidget {
  final Widget child;

  Session({this.child});

  @override
  SessionState createState() => SessionState();

  static SessionState of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_Session) as _Session).data;
  }
}

class SessionState extends State<Session> {
  ListPagePreferences _myListPrefs = ListPagePreferences();

  //called when the user logs out, for example
  void clear() {
    setState(() {
      _myListPrefs = ListPagePreferences();
    });
  }

  ListPagePreferences get myListPrefs => _myListPrefs;

  void updatePrefs({
    ListPagePreferences prefs,
    rowsPerPage,
    startIndex,
    sortColumnIndex,
    sortAscending,
    searchValue,
    filter,
  }) {
    setState(() {
      prefs.updatePrefs(
        rowsPerPage: rowsPerPage,
        startIndex: startIndex,
        sortColumnIndex: sortColumnIndex,
        sortAscending: sortAscending,
        searchValue: searchValue,
        filter: filter,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return _Session(
      data: this,
      child: widget.child,
    );
  }
}

class _Session extends InheritedWidget {
  final SessionState data;

  _Session({Key key, this.data, Widget child}) : super(key: key, child: child);

  @override
  bool updateShouldNotify(_Session old) => true;
}

Мое приложение затем обернулось этим унаследованным виджетом:

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Session(
      child: MaterialApp(
        title: "My App",
        home: WelcomePage(),
      ),
    );
  }
}

Это означает, что из любого места в приложении я могу получить доступСеанс и хранить вещи в нем.То, как оно используется в любом месте приложения, выглядит так:

ListPagePreferences savedPrefs = Session.of(context).myListPrefs;

Есть и другие способы сохранения состояния, но это было довольно просто и легко для наших нужд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...