我有一个底部导航栏,可以在同一个屏幕中的类之间导航。
我的主要构建小部件:
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
body: PageStorage(
child: Stack(
children: <Widget>[currentPage, bottomBar()],
),
bucket: bucket,
),
),
);
}
我的底部栏
Widget bottomBar() {
return Column(
children: <Widget>[
const Expanded(
child: SizedBox(),
),
BottomBarView(
tabIconsList: tabIconsList,
addClick: () {},
changeIndex: (int index) {
setState(() {
currentTab = index;
currentPage = pages[index];
print(pages[index]);
print(currentTab);
});
},
),
],
);
}
底部栏工作正常,但每次按下按钮,它都会一次又一次地重新构建同一个类,尽管我使用的是桶和PageStoorage。我如何才能停止重建课程呢?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Flutter中,页面重建通常是由于setState或者其他导致Widget树变化的操作引起的。你已经尝试使用PageStorage
来缓存页面状态以避免不必要的重建,这是一个正确的方向。但是,从你的描述来看,问题可能在于每次切换tab时,你实际上都在创建一个新的Widget实例(通过pages[index]
)而不是复用已有的实例。
为了优化并避免不必要的重建,你可以考虑以下几种策略:
使用IndexedStack: IndexedStack可以保存其子Widgets的状态,只显示当前选中的Widget。这样,当页面切换时,其他页面不会被重建。
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
body: PageStorage(
child: IndexedStack(
index: currentTab,
children: pages,
),
bucket: bucket,
),
),
);
}
这里,pages
列表应包含实际的页面Widget,而不再是每次切换时动态创建。
使用AutomaticKeepAliveClientMixin: 如果你的页面是StatefulWidget,并且它们的内容不经常改变,可以混入AutomaticKeepAliveClientMixin
来告诉框架即使页面不在视图中也应保持其状态。 在每个页面的State类中添加:
class YourPage extends StatefulWidget {
// ...
}
class YourPageState extends State<YourPage> with AutomaticKeepAliveClientMixin<YourPage> {
@override
bool get wantKeepAlive => true; // 告诉系统需要保持此页面状态
// ...
}
重用页面实例: 确保在初始化时就创建好所有页面的实例,并在切换时不重新创建,而是直接引用已存在的实例。
检查BottomBarView内部逻辑: 确保BottomBarView
的changeIndex
回调没有触发任何不必要的重建。如果它也在进行setState或有其他引起重建的操作,请优化这部分逻辑。
综上所述,使用IndexedStack
可能是最直接有效的方法来减少页面重建,同时结合适当的状态管理策略,如使用Provider、Riverpod或Bloc等,可以进一步优化应用性能和用户体验。