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" 喜欢 messagemessageLenghtmessageList、在 _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(),
    );
  }

我把类合二为一,调用函数绘制留言卡,成功了,谢谢大家的帮助和关注