Flutter 调用 setState() 在另一个 class 中更新 UI
Flutter call setState() to update UI in another class
我正在尝试在按下按钮时调用 setState,以便 ui 可以显示新列表,但即使使用我无法使用 setState 的函数,否则它会给我一个错误,说我在 a 中调用 setState构造函数。
这是我的 statlessWidget 代码:
class _MessageCard extends StatelessWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
_MessageCard(
{@required this.message,
@required this.messageLenght,
@required this.messageList});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 600,
child: InkWell(
child: Container(
width: 900,
color: Colors.grey[200],
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Center(
child: Container(
width: 600,
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
child: Icon(
Icons.notifications,
color: Colors.red[400],
),
backgroundColor: Colors.grey[200],
),
title: Text(
(this.message.vDescricao ?? '').trim(),
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
subtitle: Text(
(this.message.vData ?? '').trim() +
' ' +
(this.message.vHora ?? '').trim(),
style: TextStyle(
color: Colors.red[400],
fontSize: 13,
),
),
trailing: FlatButton(
child: Text(
Translations.of(context)
.trans('finishmessageshort'),
),
onPressed: () => _showDeleteAlertMessage(
this.message.vNumero, context)),
),
Divider(
color: Colors.black54,
),
],
),
),
),
),
),
),
));
}
Future _showDeleteAlertMessage(String id, BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(
Translations.of(context).trans('finishmessage') + '?',
),
actions: <Widget>[
FlatButton(
child: new Text(
Translations.of(context).trans('closealert'),
),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: new Text(("Ok")),
onPressed: () =>
{_deleteMessage(id), Navigator.of(context).pop()},
)
],
);
});
}
_deleteMessage(String id) async {
for (i = 0; i < this.messageLenght; i++) {
if (this.messageList[0].vNumero == this.message.vNumero) {
this.messageList.removeAt(i);
_HomePageState().mensagemRepo.confirmMessage(this.message.vNumero);
await _HomePageState()._getMessages();
return this.messageList;
}
}
}
}
这是我的 _getMessages()
_getMessages() async {
setState(() {
_loading = true;
_errorMsg = '';
});
try {
_messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
} catch (e) {
_errorMsg = e.toString();
}
setState(() {
_loading = false;
});
}
我怎样才能使用这个 setState?
感谢您的时间和关注
编辑:现在更新列表但不更新 UI,因为我无法从 MessageCard
设置主页状态
您只能在 StatefulWidget
中使用 setState
。
class MessageCard extends StatefulWidget {
@override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
@override
Widget build(BuildContext context) {
// your build method here
}
}
嗯,您不能为不存在的东西设置值。无状态本身就清楚地表明它不能保持任何状态。将小部件更改为有状态小部件会起作用。
无状态小部件一旦呈现就无法更改状态。要使用 setState 并重新呈现小部件,请使用 StatefulWidget。
只需将您的 MessageCard 从 Stateless Widget 更改为 StatefulWidget
class MessageCard extends StatefulWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
MessageCard(
{@required this.message,
@required this.messageLenght,
@required this.messageList});
@override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
@override
Widget build(BuildContext context) {
// your build method here
}
}
此外,现在 "to use your MessageCard properties" 喜欢 message、messageLenght、messageList、在 _MessageCardState 你必须使用 属性 像 widget.message, widget.messageList 和 widget.message 长度 。
这可以刷新 ui 吗?
_getMessages() async {
_HomePageState()._messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
setState(() {
_HomePageState()._messagesList();
});
}
_messagesList() 的代码是:
SliverChildBuilderDelegate _messagesList() {
int count() {
if (_errorMsg != '')
return 1;
else
return _messages == null ? 0 : _messages.length;
}
return SliverChildBuilderDelegate(
(BuildContext context, int index) {
print("i: $index");
if (_errorMsg != '') {
return Padding(
padding: EdgeInsets.all(20),
child: ErrorMessage(
error: _errorMsg,
),
);
} else {
return _MessageCard(
message: this._messages[index],
messageLength: this._messages.length,
messageList: this._messages);
}
},
childCount: count(),
);
}
我把类合二为一,调用函数绘制留言卡,成功了,谢谢大家的帮助和关注
我正在尝试在按下按钮时调用 setState,以便 ui 可以显示新列表,但即使使用我无法使用 setState 的函数,否则它会给我一个错误,说我在 a 中调用 setState构造函数。
这是我的 statlessWidget 代码:
class _MessageCard extends StatelessWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
_MessageCard(
{@required this.message,
@required this.messageLenght,
@required this.messageList});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 600,
child: InkWell(
child: Container(
width: 900,
color: Colors.grey[200],
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Center(
child: Container(
width: 600,
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
child: Icon(
Icons.notifications,
color: Colors.red[400],
),
backgroundColor: Colors.grey[200],
),
title: Text(
(this.message.vDescricao ?? '').trim(),
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
subtitle: Text(
(this.message.vData ?? '').trim() +
' ' +
(this.message.vHora ?? '').trim(),
style: TextStyle(
color: Colors.red[400],
fontSize: 13,
),
),
trailing: FlatButton(
child: Text(
Translations.of(context)
.trans('finishmessageshort'),
),
onPressed: () => _showDeleteAlertMessage(
this.message.vNumero, context)),
),
Divider(
color: Colors.black54,
),
],
),
),
),
),
),
),
));
}
Future _showDeleteAlertMessage(String id, BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(
Translations.of(context).trans('finishmessage') + '?',
),
actions: <Widget>[
FlatButton(
child: new Text(
Translations.of(context).trans('closealert'),
),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: new Text(("Ok")),
onPressed: () =>
{_deleteMessage(id), Navigator.of(context).pop()},
)
],
);
});
}
_deleteMessage(String id) async {
for (i = 0; i < this.messageLenght; i++) {
if (this.messageList[0].vNumero == this.message.vNumero) {
this.messageList.removeAt(i);
_HomePageState().mensagemRepo.confirmMessage(this.message.vNumero);
await _HomePageState()._getMessages();
return this.messageList;
}
}
}
}
这是我的 _getMessages()
_getMessages() async {
setState(() {
_loading = true;
_errorMsg = '';
});
try {
_messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
} catch (e) {
_errorMsg = e.toString();
}
setState(() {
_loading = false;
});
}
我怎样才能使用这个 setState?
感谢您的时间和关注
编辑:现在更新列表但不更新 UI,因为我无法从 MessageCard
设置主页状态您只能在 StatefulWidget
中使用 setState
。
class MessageCard extends StatefulWidget {
@override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
@override
Widget build(BuildContext context) {
// your build method here
}
}
嗯,您不能为不存在的东西设置值。无状态本身就清楚地表明它不能保持任何状态。将小部件更改为有状态小部件会起作用。
无状态小部件一旦呈现就无法更改状态。要使用 setState 并重新呈现小部件,请使用 StatefulWidget。
只需将您的 MessageCard 从 Stateless Widget 更改为 StatefulWidget
class MessageCard extends StatefulWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
MessageCard(
{@required this.message,
@required this.messageLenght,
@required this.messageList});
@override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
@override
Widget build(BuildContext context) {
// your build method here
}
}
此外,现在 "to use your MessageCard properties" 喜欢 message、messageLenght、messageList、在 _MessageCardState 你必须使用 属性 像 widget.message, widget.messageList 和 widget.message 长度 。
这可以刷新 ui 吗?
_getMessages() async {
_HomePageState()._messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
setState(() {
_HomePageState()._messagesList();
});
}
_messagesList() 的代码是:
SliverChildBuilderDelegate _messagesList() {
int count() {
if (_errorMsg != '')
return 1;
else
return _messages == null ? 0 : _messages.length;
}
return SliverChildBuilderDelegate(
(BuildContext context, int index) {
print("i: $index");
if (_errorMsg != '') {
return Padding(
padding: EdgeInsets.all(20),
child: ErrorMessage(
error: _errorMsg,
),
);
} else {
return _MessageCard(
message: this._messages[index],
messageLength: this._messages.length,
messageList: this._messages);
}
},
childCount: count(),
);
}
我把类合二为一,调用函数绘制留言卡,成功了,谢谢大家的帮助和关注