我是 flutter 和 dart 的新手,我正在尝试使用 .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 并且它重新插入收到的最后一条消息之外,一切正常在屏幕上,所有其他人都不会出现,直到我与屏幕交互,例如弹出键盘。我真的不明白我做错了什么。