Flutter Stateful Widget 重新创建 State
Posted
技术标签:
【中文标题】Flutter Stateful Widget 重新创建 State【英文标题】:Flutter Stateful Widget recreates State 【发布时间】:2019-07-26 22:56:49 【问题描述】:我正在开发一个颤振应用程序,并发现状态管理出现意外行为。我创建了一个示例应用程序来重现该行为,您可以在下面找到代码和日志输出。
该应用程序包含一个简单的 ListView,其中包含 10 个有状态的容器(文本 + 装饰)。 当我向下滚动时,每个容器及其容器状态将按预期创建一次。当我再次向上滚动时,Flutter 会为再次出现在显示屏上的每个容器小部件重新创建每个状态(但不是容器小部件)。 我希望颤振会在不重新创建整个状态对象的情况下检索先前的状态。 我在这里做错了吗?
示例代码:
class MyHomePage extends StatefulWidget
MyHomePage(Key key) : super(key: key)
print("MyHomePage constructor");
@override
_MyHomePageState createState()
print("createState");
return _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
_MyHomePageState()
print("_MyHomePageState contructor");
void initState()
super.initState();
print("_MyHomePageState initState");
@override
Widget build(BuildContext context)
return Scaffold(
body: ListView.builder(
itemBuilder: (context, index)
return ContainerWidget(index, key: ValueKey(index));
,
itemCount: 10,
));
class ContainerWidget extends StatefulWidget
int index;
ContainerWidget(this.index, key) : super(key: key)
print("ContainerWidget constructor for index $index");
@override
State<StatefulWidget> createState()
print("ContainerWidget createState for index $index");
return _ContainerState();
class _ContainerState extends State<ContainerWidget>
_ContainerState()
print("_ContainerState constructor");
void initState()
super.initState();
print("_ContainerState initState for index $widget.index");
@override
Widget build(BuildContext context)
return Container(
child: Center(
child: Text("Index: $widget.index"),
),
height: 200,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.green),
),
),
);
日志输出:
I/flutter (22400): createState
I/flutter (22400): _MyHomePageState contructor
I/flutter (22400): _MyHomePageState initState
I/flutter (22400): ContainerWidget constructor for index 0
I/flutter (22400): ContainerWidget createState for index 0
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 0
I/flutter (22400): ContainerWidget constructor for index 1
I/flutter (22400): ContainerWidget createState for index 1
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 1
I/flutter (22400): ContainerWidget constructor for index 2
I/flutter (22400): ContainerWidget createState for index 2
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 2
I/flutter (22400): ContainerWidget constructor for index 3
I/flutter (22400): ContainerWidget createState for index 3
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 3
I/flutter (22400): ContainerWidget constructor for index 4
I/flutter (22400): ContainerWidget createState for index 4
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 4
I/flutter (22400): ContainerWidget constructor for index 5
I/flutter (22400): ContainerWidget createState for index 5
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 5
I/flutter (22400): ContainerWidget createState for index 1
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 1
I/flutter (22400): ContainerWidget createState for index 0
I/flutter (22400): _ContainerState constructor
I/flutter (22400): _ContainerState initState for index 0
【问题讨论】:
【参考方案1】:这是意料之中的,因为项目在离开屏幕时会被卸载。
如果你不想这样,你会想要使用我们所说的“保持活力”。
你可以通过在 State
类中添加一个 mixin 来做到这一点:
class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin
bool get wantKeepAlive => true;
// ...
【讨论】:
假设我想开发一个带有 n 容器的中心页面。每个容器处理不同复杂度的任务,例如从远程获取和处理数据。在您看来,将 AutomaticKeepAliveClientMixin 添加到每个容器中是最好的解决方案,还是像 SingleChildScrollView 这样包含 n 个容器的列?我想防止在滚动时不会一遍又一遍地调用任务。以上是关于Flutter Stateful Widget 重新创建 State的主要内容,如果未能解决你的问题,请参考以下文章
Flutter控件篇(Stateful widget)——ListView
Flutter - Stateful(有状态) 和 stateless(无状态) widgets
跨多个屏幕使用的 Flutter Stateful Widget 正在重建
Flutter Stateful Widget 状态未初始化