首页 文章

Flutter中的状态更新

提问于
浏览
2

我有一个了解国家如何运作的问题 .
我在我的应用程序中设置了一个页面作为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 回答

  • 2

    这是预期的行为 . 当父重建flutter将新窗口小部件树与旧窗口小部件树进行比较时 .

    通过这种方式,flutter能够知道哪些小部件被“更新”并且被添加/删除了哪些小部件 .

    对于添加的小部件,它将创建一个新状态 . initState 被调用 . 对于更新的小部件; flutter将重用旧的小部件并通过将旧的"widget"部分作为参数传递给参数来调用 didUpdateWidget . 至于删除的小部件,它将调用 dispose .

    在您的情况下,您希望再次调用 initState . 但事实上它得到了"updated" .


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

    实现 didUpdateWidget . 哪会重置你的状态或做你想做的任何其他事情 . 这是您应该考虑的最佳方法 . 因为您不一定要重置"new statefulwidget"的子项 .

    还有"lazy"解决方案,这是告诉flutter "Hey, this is a different widget. don't reuse the old one" . 这是使用 Key 实现的 .

    密钥用法的更多信息here

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

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

相关问题