我正在使用材质库的Drawer
类创建带有导航抽屉的Flutter应用程序。包含Widget
的{{1}}是Drawer
,并且StatefulWidget
的内容根据导航抽屉上的选定项目显示。内容为Scaffold
或WidgetOne
,两者都保持自己的状态为WidgetTwo
。请参见下面的代码示例。
此刻,当我从一个小部件更改为另一个小部件并返回时,先前显示的小部件的整个状态将重新加载。这是不理想的,因为两个小部件都通过API进行了网络调用,因此需要相应地重新绘制。
StatefulWidget
,如此处建议的那样:https://stackoverflow.com/a/50074067/4009506。但是,这似乎不起作用。AutomaticKeepAliveClientMixin
:https://stackoverflow.com/a/54999503/4009506。即使尚未显示所有小部件,这也将直接加载。IndexedStack
class DrawerWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => _DrawerState();
}
class _DrawerState extends State<DrawerWidget> {
Widget _activeWidget;
@override
void initState() {
_activeWidget = FirstWidget();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Drawer demo")),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text("First Widget"),
onTap: () {
setState(() {
_activeWidget = FirstWidget();
});
},
),
ListTile(
title: Text("Second Widget"),
onTap: () {
setState(() {
_activeWidget = SecondWidget();
});
},
),
],
),
),
body: _activeWidget);
}
}
class FirstWidget extends StatefulWidget {
// [..]
}
class SecondWidget extends StatefulWidget {
// [..]
}
和WidgetOne
仅在初始加载时加载(在WidgetTwo
中选择它们后)。如果先前已加载过该小部件,则切换回另一个小部件不应重新加载该小部件。子窗口小部件不应仅在初次按下时直接全部加载。
每次在Drawer
中被选中时,FirstWidget
和SecondWidget
都被重新加载和重绘。
答案 0 :(得分:0)
我通过使用PageView
并在所有子窗口小部件上实现了AutomaticKeepAliveClientMixin
解决了这个问题:
class DrawerWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => _DrawerState();
}
class _DrawerState extends State<DrawerWidget> {
final _pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Drawer demo")),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text("First Widget"),
onTap: () {
_pageController.jumpToPage(0);
},
),
ListTile(
title: Text("Second Widget"),
onTap: () {
_pageController.jumpToPage(1);
},
),
],
),
),
body: PageView(
controller: _pageController,
children: <Widget>[
FirstWidget(),
SecondWidget()
],
physics: NeverScrollableScrollPhysics()
));
}
}
class FirstWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => _FirstWidgetState();
}
class _FirstWidgetState extends State<FirstWidget> with AutomaticKeepAliveClientMixin<FirstWidget> {
// [..]
@override
bool get wantKeepAlive => true;
}
class SecondWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => _SecondWidgetState();
}
class _SecondWidgetState extends State<SecondWidget> with AutomaticKeepAliveClientMixin<SecondWidget> {
// [..]
@override
bool get wantKeepAlive => true;
}
现在,所有小部件仅在初次切换时才在导航抽屉中加载,而在切换回时不会重新加载。