flutter - 无法从静态方法调用 Flutter Stateful Widget 的 setState
问题描述
我在显示列表视图的地方有以下代码,并且此列表视图从列表中获取数据,该列表可以onConnect()
从STOMP
. 所以这个 onConnect 方法应该是静态的。
现在,当我从 WebSocket 接收数据时,会调用这个 onConnect 方法,它将值插入到列表中。但是列表视图没有得到更新。我无法调用setState()
,以便使用新数据重新渲染小部件,因为此onConnect()
方法是静态的。
对此的任何解决方案。
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
方法,您需要在实例方法内部,而不是静态(类)方法。因此response
,onConnectCallback
在这种情况下,方法不应该是静态的。因为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
}
...
推荐阅读
- python-3.x - 需要在 Azure ML studio 中安装 python 包
- c - 尝试使用 C 套接字接受与 Pthread 的新连接
- android - 从 HashMap 设置 ImageView src
- java - 使用动态相关 ID 从 ibm mq 异步接收值
- xamarin - 如何将垂直和水平居中的文本标签添加到我在 C# 中创建的网格中
- java - 在java中的列表列表中分组列表元素
- c# - NuGet 依赖策略
- python - 如何在 SQLAlchemy + Postgres 中将具有空数组的数组列设置为默认值
- java - Cucumber、java、maven、Junit 扩展报告未生成
- google-drive-api - Prestashop 将图像上传到 Google 云端硬盘