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