如何解决Flutter:当父母的状态改变时,子小部件的状态会丢失
我正在学习 Flutter 并且正在努力解决一些状态管理问题。
我有一个 HomeScreen 小部件,其中包含 Scaffold 和一个 BottomNavigationBar。要根据BottomNavigationBar 中选定的选项卡切换页面,我将PageView 与PageController 一起使用。以下是 HomeScreen 小部件的 build
方法的外观:
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: _currentIndex == 2,appBar: AppBar(...properties),body: PageView(
controller: _pageController,children: _pages,),bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[...items],currentIndex: _currentIndex,onTap: _onItemTapped,//This changes state _currentIndex and calls the method _pageController.jumpToPage(_currentIndex);
),);
}
-
_currentIndex
最初为 0。 -
_pages
是一个包含 3 个小部件的列表。 -
_pageController
是一个简单的 PageController,initialPage 设置为 0。
如果您注意到我正在使用使用 extendBodyBehindAppBar: _currentIndex == 2
状态的属性 _currentIndex
,这会导致问题。
当我点击 BottomNavigationBar 上的最后一个 Tab 时,状态 _currentIndex
更改为 2,因此 extendBodyBehindAppBar
设置为 true
,这使得整个 Scaffold 重建自身,PageView 的状态为丢失了。
如果注释掉 extendBodyBehindAppBar: _currentIndex == 2
行,那么即使 Scaffold 重建了 PageView 小部件的状态。
据我所知,即使父级重建,Flutter 也应该保持子级 Widgets 的状态,因为 WidgetTree 没有改变或重新排列。我尝试在 PageView 上使用 Key 但没有任何效果。
非常感谢任何帮助。
解决方法
参考Lucas Salton Cardinali post on medium 你需要使用PageStorage来持久化你需要的child被销毁后的状态。
这里是从同一页面检索的示例:
import 'package:flutter/material.dart';
// ...
void main() => runApp(MyApp());
// ...
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<Widget> pages = <Widget>[
ColorBoxPage(
key: PageStorageKey('pageOne'),),ColorBoxPage(
key: PageStorageKey('pageTwo'),)
];
int currentTab = 0;
final PageStorageBucket _bucket = PageStorageBucket();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Persistence Example"),body: PageStorage(
child: pages[currentTab],bucket: _bucket,bottomNavigationBar: BottomNavigationBar(
currentIndex: currentTab,onTap: (int index) {
setState(() {
currentTab = index;
});
},items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),label: 'page 1',BottomNavigationBarItem(
icon: Icon(Icons.settings),label: 'page2',],);
}
}
class ColorBoxPage extends StatelessWidget {
ColorBoxPage({
Key? key,}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemExtent: 250.0,itemBuilder: (context,index) => Container(
padding: EdgeInsets.all(10.0),child: Material(
color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,child: Center(
child: Text(index.toString()),);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。