gpt4 book ai didi

dart - setState 不更新用户界面

转载 作者:IT王子 更新时间:2023-10-29 06:50:14 27 4
gpt4 key购买 nike

在使用借助定时器 self 更新的有状态小部件时,我一直面临与 setState 函数相关的一些问题。下面的代码显示了 2 个主要类,它们复制了我是如何发现这个错误的。文本小部件“Lorem”应在 10 秒内插入 - 它是 - 但从未显示。我尝试调试数组“Items”,它在 5 秒后确实包含“lorem”文本小部件,这是应该的。 “构建”函数运行但在 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 中。

最佳答案

这是错误的地方:

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

video

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<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();
}

class _textClass extends State<textClass>
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
void dispose() {
super.dispose();
timer.cancel();
}


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

关于dart - setState 不更新用户界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45827785/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com