Flutter 中的状态更新

Posted

技术标签:

【中文标题】Flutter 中的状态更新【英文标题】:State updates in Flutter 【发布时间】:2018-10-16 20:07:04 【问题描述】:

我是 Flutter 新手,在理解状态如何工作时遇到了问题。 我在我的应用程序中设置了一个页面作为 StatefulWidget,然后在该页面的状态中,主要组件之一是一个单独的 StatefulWidget。

内部小部件显示一个问题并允许用户输入答案。

然后我想做的是在同一页面上显示下一个答案。

输入答案后,我的内部小部件回调到我的页面状态。

我试图用另一个副本替换我的内部小部件,但是状态未重置。那就是没有创建新状态,并且永远不会再次调用 initState()。

我应该使用特定的调用或方法来实现这一点吗?

编辑:例如,如果我有以下内容

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 

  @override
  void initState()
     changeContent();
  

  Widget innerWidget;
  void changeContent()
     setState(()
        innerWidget = new CustomStatefullWidget();
     
  

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            innerWidget
          ],
        ),
      ),
    );
  

CustomStatefullWidget 是我创建的一个类,它是页面的独立交互部分。对于此示例,实际内容应该无关紧要。

我的预期是,每当调用changeContent() 时,innerWidget 就会有一个新状态,但事实并非如此。该状态已存储在树中,并且在创建小部件的新实例时不会刷新。 如何强制颤振清除树的那部分或识别我想要重置状态?

【问题讨论】:

你能发布实际代码吗?还不清楚 我已经编辑了一个示例,这是否说明了我的要求? 更清楚了,谢谢!我添加了一个答案 【参考方案1】:

这是预期的行为。当父级重建颤振时,将新的小部件树与旧的进行比较。

这样,flutter 能够知道哪些小部件“更新”了,哪些小部件被添加/删除了。

对于添加的小部件,它将创建一个新状态。 initState 被调用。对于更新的小部件; Flutter 将重用旧的小部件并调用didUpdateWidget,方法是将旧的“小部件”部分作为参数传递。至于移除的小部件,它会调用dispose

在您的情况下,您希望再次调用 initState。但实际上它已经“更新”了。


从这一点来看,您有两种重置状态的解决方案:

实现didUpdateWidget。这将重置您的状态或做任何您想做的事情。 这是您应该考虑的最佳方法。因为您不一定要重置“新 statefulwidget”的孩子。

还有一个“懒惰”的解决方案,就是告诉flutter“嘿,这是一个不同的小部件。不要重复使用旧的”。这是使用Key 实现的。

更多关于密钥使用的信息here

这就像将您的 changeContent 方法更改为以下内容一样简单:

Widget innerWidget;
void changeContent()
  setState(()
      innerWidget = new CustomStatefullWidget(key: new UniqueKey());
  

【讨论】:

以上是关于Flutter 中的状态更新的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 的 iOS 构建更新为 TestFlight 但在 Activity 会话中的“处理”状态后消失

更新示例计数器中的非立即状态 - BloC Flutter

Flutter 中的多页面状态处理

Flutter Bloc - Flutter Bloc 状态未更新

flutter中的状态管理Provider

Flutter ListView 与 List 中的小部件不会在应该更新时更新