setState不更新用户界面

时间:2017-08-22 22:13:47

标签: dart flutter dart-async

我在使用有状态窗口小部件时遇到了与setState函数相关的一些问题,而在Timers的帮助下自我更新。下面的代码显示了2个主要类,它们复制了我如何找到此错误。文本小部件“Lorem”应该在10秒内插入 - 它是 - 但它从未显示过。我尝试调试数组“Items”,并且确实在5秒后包含“lorem”Text Widget,就像它应该的那样。 “构建”功能运行但在UI中没有任何区别。

class textList extends StatefulWidget {

  @override
  State<StatefulWidget> createState() =>
      new _textListState();
}

class _textListState extends State<textList>
    with TickerProviderStateMixin {

  List<Widget> items = new List();
  Widget lorem = new textClass("Lorem");
  Timer timer;

  @override
  void initState() {
    super.initState();

    items.add(new textClass("test"));
    items.add(new textClass("test"));

    timer = new Timer.periodic(new Duration(seconds: 5), (Timer timer) {
      setState(() {
        items.removeAt(0);
        items.add(lorem);
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    timer.cancel();
  }

  @override
  Widget build(BuildContext context) {
    Iterable<Widget> content = ListTile.divideTiles(
        context: context, tiles: items).toList();

    return new Column(
      children: content,
    );
  }
}

class textClass extends StatefulWidget {
  textClass(this.word);

  final String word;

  @override
  State<StatefulWidget> createState() =>
      new _textClass(word);
}

class _textClass extends State<textClass>
    with TickerProviderStateMixin {
  _textClass(this.word);

  String word;
  Timer timer;

  @override
  void initState() {
    super.initState();

    timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) {
      setState(() {
        word += "t";
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    timer.cancel();
  }


  @override
  Widget build(BuildContext context) {
    return new Text(word);
  }
}

这不是我找到这个错误的方法,但这是复制它的最简单方法。主要思想是:儿童文本应该不断更新(在这种情况下,最后添加“t”),5秒后,最后一个应该替换为文本小部件“Lorem”,会发生什么在列表中但不在UI中。

1 个答案:

答案 0 :(得分:3)

这是错的:

  • State永远不应该有任何构造函数参数。使用widget属性可以访问关联的StatefulWidget
  • 的最终属性
  • Flutter正在重用您的_textClass实例,因为类名和键匹配。这是一个问题,因为您只在widget.word中设置了initState,因此您没有获取新的word配置信息。您可以通过为StatefulWidget个实例提供唯一键来消除歧义并导致旧的State处理,或者您可以保留旧的State并实施{{1} }。后一种方法如下所示。

video

didUpdateWidget