我在使用有状态的小部件时遇到了一些与setState函数有关的问题,这些小部件在计时器的帮助下进行了自我更新。 下面的代码显示了2个主要类,它们复制了我如何找到此错误的方法。该文本组件“排版”应该在10秒内插入-这是- ,但它从来没有显示。我试图调试数组“ Items”,并且 在5秒钟后确实包含 “ lorem” Text Widget,这是应该的。“ build”功能可以运行,但在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”,这会发生什么情况在列表中,但不在用户界面中。
这是怎么回事:
State
widget
StatefulWidget
Flutter正在重用您的_textClass实例,因为类名和键匹配。这是一个问题,因为您仅进行了设置widget.word,initState因此您不会选择新的word配置信息。您可以通过为StatefulWidget实例提供唯一的键来消除它们的歧义并导致旧State的东西被处置来解决此问题,或者可以保留旧的东西State并加以实施didUpdateWidget。后一种方法如下所示。
Flutter
_textClass
widget.word
initState
didUpdateWidget
import ‘dart:async’; import ‘package:flutter/material.dart’;
void main() { runApp(new MaterialApp( home: new Scaffold( appBar: new AppBar(title: new Text(‘Example App’)), body: new textList(), ), )); }
class textList extends StatefulWidget {
@override State createState() => new _textListState(); }
class _textListState extends State with TickerProviderStateMixin {
List 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 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 createState() => new _textClass(); }
class _textClass extends State with TickerProviderStateMixin { _textClass();
String word; Timer timer;
@override void didUpdateWidget(textClass oldWidget) { if (oldWidget.word != widget.word) { word = widget.word; } super.didUpdateWidget(oldWidget); }
@override void initState() { super.initState(); word = widget.word;
timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) { setState(() { word += "t"; }); });
@override Widget build(BuildContext context) { return new Text(word); } }