Flutter: почему навигаторы сбрасываются при добавлении в дерево?

#flutter

#флаттер

Вопрос:

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

 class HomeView extends StatefulWidget {
  final String title;
  HomeView({this.title});
  @override
  _HomeViewState createState() => _HomeViewState(title: title);
}

class ViewData {
  Widget Function() _create;
  Widget _cache;

  Widget get view {
    if (_cache == null) {
      _cache = Navigator(
          key: GlobalKey<NavigatorState>(),
          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute(
                builder: (BuildContext context) {
                  return _create();
                },
                settings: settings);
          });
    }
    return _cache;
  }

  ViewData(this._create);
}

class _HomeViewState extends State<HomeView> {
  String title;
  int _viewIndex = 0;
  final List<ViewData> _views = [
    ViewData(() => TodayView()),
    ViewData(() => RecordView()),
    ViewData(() => MoreView(key: GlobalKey())),
  ];

  // Constructor
  _HomeViewState({this.title});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: IndexedStack(
        index: _viewIndex,
        children: _views.map((view) => view.view).toList(),
      ),
      bottomNavigationBar: BottomNavigationBar(
        onTap: (index) {
          setState(() => _viewIndex = index);
        },
        currentIndex: _viewIndex,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.access_alarm), label: "TODAY"),
          BottomNavigationBarItem(icon: Icon(Icons.wysiwyg), label: "WORK RECORD"),
          BottomNavigationBarItem(icon: Icon(Icons.more_horiz), label: "MORE"),
        ],
      ),
    );
  }
}
 

Это работает в том смысле, что когда я выполняю a .push(...) , чтобы добавить представление в один из моих Navigator экземпляров, затем меняю вкладки, а затем меняю обратно, стек навигатора остается таким, каким я его оставил, с отображаемым отображаемым видом.

Но если я удалю IndexedStack из build(...) функции следующим образом:

       body: _views[_viewIndex].view,
 

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

Я бы подумал, что из-за того, что я кэширую навигаторы в списке, новости не будут создаваться, поэтому я предполагаю, что это как-то связано с жизненным циклом виджета, когда он добавляется в дерево.

Причина, по которой я не хочу использовать an IndexedStack , заключается в том, что он загружает все виджеты заранее, а некоторые будут включать запросы к базе данных, поэтому я бы предпочел ленивую загрузку. Я полагаю, что могу как-то изменить виджеты, чтобы они загружались медленно, но я бы предпочел просто не загружать их вообще, пока пользователь не переключится на них.

Кто-нибудь может уточнить жизненный цикл, когда виджет удаляется и добавляется обратно в дерево пользовательского интерфейса? И есть ли какие-либо другие подходы, которые могли бы лучше работать при сохранении стека каждого навигатора?

Ответ №1:

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