繁体   English   中英

无法从 static 方法调用 Flutter Stateful Widget 的 setState

[英]Unable to call setState of Flutter Stateful Widget from a static method

我在显示列表视图的地方有以下代码,并且此列表视图从列表中获取数据,该列表可以从STOMPonConnect()方法动态更新。 所以这个onConnect方法预计是static。

现在,当我从 WebSocket 接收数据时,将调用此 onConnect 方法,该方法将值插入列表中。 但是列表视图没有得到更新。 我无法调用setState()以便使用新数据重新渲染小部件,因为此onConnect()方法是 static。

对此的任何解决方案。

List<ChatEntity> chats;
String chatRoomId;
String currentUserEmail;

class Chat extends StatefulWidget {

  Chat(String chatRoomIdC, String currentUserEmailC) {
    chatRoomId = chatRoomIdC;
    currentUserEmail = currentUserEmailC;
  }

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  TextEditingController messageEditingController = new TextEditingController();
 
  _ChatState() {
    client.activate();
  }

  StompClient client = StompClient(
    config: StompConfig(
        url: 'ws://localhost:8080/ws',
        onConnect: onConnectCallback,
        onWebSocketError: (dynamic error) => print(error.toString())),
  );

  static onConnectCallback(StompClient client, StompFrame connectFrame) {
    client.subscribe(
        destination: '/topic/messages/$chatRoomId',
        headers: {},
        callback: (frame) {
          response(frame);
        });
  }

  static response(StompFrame frame) {
    String response = frame.body;
    final parsed = json.decode(response).cast<Map<String, dynamic>>();
    chats.insert(
        0,
        parsed
            .map<ChatEntity>((json) => ChatEntity.fromJson(json))
            .toList()[0]);

 // call setState here to re- render the widget
  }

  Widget chatMessages() {
    return ListView.builder(
        reverse: true,
        itemCount: chats == null ? 0 : chats.length,
        itemBuilder: (context, index) {
          return MessageTile(
            message: chats[index].message,
            sendByMe: currentUserEmail == chats[index].sentBy,
          );
        });
  }

  addMessage() {
    if (messageEditingController.text.isNotEmpty) {
      Map<String, dynamic> chatMessageMap = {
        "chatroomId": chatRoomId,
        "sentBy": currentUserEmail,
        "message": messageEditingController.text
      };
      client.send(
          destination: '/app/chat',
          body: jsonEncode(chatMessageMap),
          headers: {});

      setState(() {
        messageEditingController.text = "";
      });
    }
  }

  @override
  void initState() {
    DatabaseMethods.getChats(chatRoomId).then((val) {
      setState(() {
        chats = val;
      });
    });
    super.initState();
  }

// ignore the build method as it just contains a Scaffold.

为了使用或访问setState方法,您需要在实例方法中,而不是 static(类)方法。 所以在这种情况下responseonConnectCallback方法不应该是 static 。 因为StompClient引用了这些方法,所以我会在实例化小部件时创建一个StompClient client实例(即在构造函数中):

class _ChatState extends State<Chat> {
  TextEditingController messageEditingController = new TextEditingController();
  
  StompClient client;
 
  // Create a StompClient instance when creating new state
  _ChatState() {
    client = StompClient(
      config: StompConfig(
        url: 'ws://localhost:8080/ws',
        onConnect: onConnectCallback,
        onWebSocketError: (dynamic error) => print(error.toString())),
    );
    client.activate();
  }
 
  onConnectCallback(StompClient client, StompFrame connectFrame) {
    ...
  }

  response(StompFrame frame) {
    ...
    // HERE YOU SHOULD BE ABLE TO USE setState() METHOD
  }
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM