flutter - StreamBuilder 不断在 HotReload 上添加数据
问题描述
我是颤振和飞镖的新手,我正在尝试使用 .Net SignalRCore 和流实现一个简单的聊天应用程序。这是我的聊天屏幕的代码:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:veo_chat/components/message_bubble.dart';
import 'package:veo_chat/constants.dart';
import 'package:veo_chat/models/message_receive_model.dart';
import 'package:veo_chat/models/message_send_model.dart';
import 'package:veo_chat/providers/chat_hub_client.dart';
import 'package:veo_chat/providers/veo_auth.dart';
import 'package:veo_chat/screens/welcome_screen.dart';
class ChatScreen extends StatefulWidget {
static const route = '/chat';
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
VeoAuth auth = VeoAuth();
bool showLoading = false;
final chatHubClient = ChatHubClient();
final StreamController<MessageReceiveModel> msgStreamController =
StreamController<MessageReceiveModel>();
final List<MessageBubble> messageWidgets = [];
String typedMessage;
String receiver = 'Veoxer';
void initiateChatHub() async {
await chatHubClient.connection.start();
chatHubClient.connection.on('ReceiveMessage', (params) {
print(params);
final message = MessageReceiveModel.fromDynamic(params[0]);
msgStreamController.sink.add(message);
});
}
@override
void initState() {
super.initState();
initiateChatHub();
}
@override
void dispose() {
msgStreamController.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () async {
setState(() {
showLoading = true;
});
try {
await auth.logout();
} catch (e) {
print('An error occured during log out.');
}
Navigator.pushNamed(context, WelcomeScreen.route);
setState(() {
showLoading = false;
});
}),
],
title: Text('⚡️Chat'),
backgroundColor: Colors.lightBlueAccent,
),
body: ModalProgressHUD(
inAsyncCall: showLoading,
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
StreamBuilder<MessageReceiveModel>(
stream: msgStreamController.stream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
var messagesData = snapshot.data;
messageWidgets.add(
MessageBubble(
senderUsername: messagesData.senderUserName,
messageBody: messagesData.messageBody,
sendTime: DateTime.tryParse(messagesData.sendTime),
),
);
}
return Expanded(
child: ListView(
children: messageWidgets,
),
);
},
),
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
typedMessage = value;
},
decoration: kMessageTextFieldDecoration,
),
),
TextButton(
onPressed: () {
chatHubClient.sendMessage(MessageSendModel(
messageBody: typedMessage,
receiverUserName: receiver,
sendTime: DateTime.now()));
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
),
);
}
}
一切正常,除了每次我的应用程序热加载时,我的 StreamBuilder 中的快照仍然将“hasData”属性设置为 true 并且它重新插入收到的最后一条消息并且由于某些其他原因,只有收到的第一条消息出现在屏幕上,在我与屏幕交互(例如弹出键盘)之前,所有其他内容都不会出现。我真的不明白我做错了什么。
解决方案
推荐阅读
- php - 限制对 Google API 的 API 访问不起作用
- prestashop-1.7 - prestashop 商店 1.7 新地址注册时出现错误 500
- flutter - 在 Column 和 ListView 内滚动时,Flutter Google Ads 会出现意想不到的故障
- stripe-payments - 试用期满后将信用卡(在应用内)添加到现有的 Stripe 订阅
- reactjs - 单击时如何更改按钮值?
- command-line - 无法逃脱空白?
- next.js - Next.js Prop `href` 不匹配。服务器:“/”客户端:“/#page3”
- c++ - 添加新用户会出现错误“无法将“const wchar_t”类型的值分配给“LPWSTR”类型的实体”
- python - 当我在 python 中创建变量时,为什么 python 会说 Expected ")"?
- haskell - 是否可以在快速检查生成器中传递和检索状态