我有两个屏幕,一个屏幕可以让用户与特定的人聊天,第二个屏幕可以让用户看到所有聊天的列表。
目的是在第二个屏幕上显示最后一条消息。这样做如下:
问题是,流生成器没有在监听新数据(不确定原因)。据我所知,当用户发送消息时,BloC正在发送新的数据流,只是不会在列表中重新呈现。
以下是该代码的简化版本:
class ChatScreen extends StatelessWidget {
final ContactsBloc _contactsBloc = ContactsBloc();
@override()
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context, true);
},
),
body: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
controller: messageTextController,
onChanged: (value) {
message = value;
},
decoration: kMessageTextFieldDecoration,
),
),
FlatButton(
onPressed: () async {
//update remote and local databases
await _contactsBloc.updateContact(
{'last_message': utf8.decode(base64.decode(message))},
'conversation_id = ?',
[conversationId]);
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
聊天屏幕:
class ChatsScreen extends StatefulWidget {
static const id = 'chats';
@override
_ChatsScreenState createState() => _ChatsScreenState();
}
class _ChatsScreenState extends State<ChatsScreen> {
final ContactsBloc _contactsBloc = ContactsBloc();
Iterable<Contact> contacts;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chats'),
body: Container(
child: StreamBuilder(
stream: _contactsBloc.contacts,
builder: (context, results) {
print('New stream: $results');
if (!results.hasData) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: CircularProgressIndicator(),
),
],
);
} else {
List contacts = results.data;
contacts = contacts
.where((element) => element.lastMessage != null)
.toList();
if (contacts.length > 0) {
return ListView.builder(
itemCount: contacts.length,
itemBuilder: (context, index) {
ContactModel contact = contacts[index];
return ChatItem(
name: contact.name,
message: contact.lastMessage,
profilePicture: contact.profilePictureUrl,
lastSeen: contact.lastSeen,
user: currentUser,
toUser: contact.uid,
conversationId: contact.conversationId,
);
},
);
}
return Container();
}
},
)),
);
}
}
联系人BloC:
class ContactsBloc {
ContactsBloc() {
getAllContacts();
}
final _contactsController = StreamController<List<ContactModel>>.broadcast();
Stream<List<ContactModel>> get contacts => _contactsController.stream;
_dispose() {
_contactsController.close();
}
getAllContacts() async {
List<ContactModel> contacts = await DatabaseProvider.db.getAllContacts();
_contactsController.sink.add(contacts);
}
updateContact(var update, String where, List whereArgs) async {
await DatabaseProvider.db.updateContact(update, where, whereArgs);
getAllContacts();
}
}
答案 0 :(得分:0)
现在尝试添加此内容以创建ContactBloc
的Singleton实例
class ContactsBloc{
ContactsBloc._();
static final ContactsBloc _instance = ContactsBloc._();
factory ContactsBloc() => _instance;
/// the rest of your code...
}
如果您希望对类(Bloc,Provider,Redux等)进行更多控制,我建议检查一些状态管理