如何解决台下导航器重建
我已经为 Offstage
实现了多个 Navigators
bottomNavigationBar
,更多详细信息可以查看 here。问题在于,在使用此方法时,每次我们选择底部导航项时,FutureBuilder
都会运行 future 方法并重建整个小部件,每个 Offstage
小部件及其所有子部件也都会重建。
对于每个 Offstage
小部件,我通过 html 请求加载数据,这意味着每次切换选项卡时,都会发出 5 个请求。
这是我的主要 Scaffold
,其中包含 bottomNavigationBar
。
@override
Widget build(BuildContext context) {
TabProvider tabProvider = Provider.of<TabProvider>(context);
return FutureBuilder(
future: initProvider(),builder: (context,snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return WillPopScope(
onWillPop: _onWillPop,child: Scaffold(
appBar: AppBar(
title: Text(tabName[tabProvider.currentTab],),body: Stack(children: <Widget>[
_buildOffstageNavigator(TabItem.feed,tabProvider.currentTab),_buildOffstageNavigator(TabItem.explore,_buildOffstageNavigator(TabItem.guide,_buildOffstageNavigator(TabItem.map,_buildOffstageNavigator(TabItem.profile,]),bottomNavigationBar: BottomNavigation(
currentTab: tabProvider.currentTab,onSelectTab: tabProvider.selectTab,);
} else {
return Text('Loading');
}
},);
}
FutureBuilder
将初始化我的提供程序中的值,以便每个选项卡都可以访问缓存的数据。
_buildOffstageNavigator
将返回以下内容
return Offstage(
offstage: currentTab != tabItem,child: TabNavigator(
navigatorKey: navigatorKeys[tabItem],tabItem: tabItem,);
下面是构建在 Scaffold
主体内部的小部件,因此位于上面的 Offstage
Navigator
内部。
@override
Widget build(BuildContext context) {
TabProvider tabProvider = Provider.of<TabProvider>(context);
States stateData = tabProvider.exploreStateCache;
return Container(
child: ListView(
children: <Widget>[
Text(stateData.stateName),Text(stateData.stateDescription),],);
}
我已遵循此 articles 建议与提供商一起使用期货,但缺少其他内容
解决方法
不是在构建方法中创建期货,正如您所注意到的,可能会被多次调用,而是在仅被调用一次的地方创建它们。例如,一个 StatefulWidget 的 initState:
class Foo extends StatefulWidget {
@override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> {
Future<MyData> _dataFuture;
@override
void initState() {
super.initState();
_dataFuture = getData();
}
@override
Widget build(BuildContext context) => FutureBuilder<MyData>(
future: _dataFuture,builder: (context,snapshot) => ...,);
}
您可以改进的第二件事是,当提供程序为 TabProvider
提供新值时,减少重建的范围。当 Provider.of<Data>(context)
有新值时,您调用 Data
的上下文会重建。使用提供程序包提供的各种其他小部件(例如 Consumer
和 Selector
)最方便地完成此操作。
因此删除 Provider<TabProvder>.of(context)
调用并使用 Consumer
和 Selector
。例如,仅在切换选项卡时重建标题:
AppBar(
title: Selector<TabProvider,String>(
selector: (context,tabProvider) => tabName[tabProvider.currentTab],title) => Text(title),),)
Selector 仅在其 Text(title)
回调的结果与先前值不同时重建 selector
小部件。 _buildOffstageNavigator
类似:
Widget _buildOffstageNavigator(BuildContext context,TabItem tabItem) {
return Selector<TabProvider,bool>(
selector: (context,tabProvider) => tabProvider.currentTab != tabItem,isCurrent) => Offstage(
offstage: isCurrent,child: Selector<TabProvider,Key>(
selector: (context,tabProvider) => tabProvider.navigatorKeys[tabItem],tabKey) => TabNavigator(
navigatorKey: tabKey,tabItem: tabItem,);
}
(注意:所有代码都未经测试并包含错别字)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。