颤抖。如何监听 Hive 框中的特定值

问题描述 投票:0回答:1

我有一个存储 ChatRoom 对象的盒子

@HiveType(typeId: 2)
class ChatRoom {
  @HiveField(1)
  String name;
  @HiveField(2)
  List<ChatMessage> chatmessage;
  ChatRoom({
    required this.name,
    required this.chatmessage,
  });
}

@HiveType(typeId: 3)
class ChatMessage {
  @HiveField(3)
  String name;
  @HiveField(4)
  String message;
  @HiveField(5)
  String time;
  @HiveField(6)
  bool isSender;
  @HiveField(7)
  String deliverStatus;
  ChatMessage(
      {required this.name,
      required this.message,
      required this.time,
      required this.isSender,
      required this.deliverStatus});
}

我使用 ValueListenableBuilder 成功监听了它们的创建和修改

return ValueListenableBuilder(
        valueListenable: Hive.box<ChatRoom>('ChatRooms').listenable(),
        builder: (context, Box<ChatRoom> _chatStorageBox, _) {
          return ListView.separated(
            separatorBuilder: (context, index) => const Divider(
              color: Colors.white,
            ),
            itemCount: _chatStorageBox.values.length,
            itemBuilder: (context, index) {
              final chatRoom = _chatStorageBox.getAt(index) as ChatRoom;
              String message = chatRoom.chatmessage.last.message;
              bool isSender = chatRoom.chatmessage.last.isSender;
              String time = chatRoom.chatmessage.last.time;
              List<ChatMessage> listOfChatMessages = chatRoom.chatmessage;

              final chatName = chatRoom.name;

              return InkWell(
                onTap: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => ChatScreen(
                                listOfmessages: listOfChatMessages,
                                userNumber: chatName,
                                server:
                                    '', 
                              )));
                },
                child: ConversationWidget(
                    isSender: isSender,
                    name: chatName,
                    messageText: message,
                    time: time),
              );
            },
          );
        });


class ChatScreen extends StatefulWidget {
  ChatScreen(
      {required this.userNumber,
      required this.server,
      required this.listOfmessages,
      Key? key})
      : super(key: key);
  String userNumber;
  String server;
  List<ChatMessage> listOfmessages;

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final _textController = TextEditingController();
  final String toNumber = 'remoteAddress';
  final String message = 'message';
  List<ChatMessage> msgList = []; // ??
  late final ValueNotifier<List<ChatMessage>> listenListOfmessages;

  @override
  void initState() {
    msgList = widget.listOfmessages;
    listenListOfmessages = ValueNotifier<List<ChatMessage>>(msgList);
    super.initState();
  }

  @override
  void dispose() {
    _textController.dispose();
    super.dispose();
  }

  static Box<ChatRoom> box = Hive.box<ChatRoom>('ChatRooms');

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

    ///////////////////////////////////////////////////
    return Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          actions: [
            IconButton(
                onPressed: () {
                  print('add contact');
                },
                icon: Image.asset('assets/images/ic_add_contact_holo_dark.png'))
          ],
          title: const Text('Tel'),
          // backgroundColor: Constants.kIconColorLightTheme,
          backgroundColor: Colors.grey[900],
        ),
        body: ChangeNotifierProvider(
          create: (_) => MessageService(),
          child: Column(
            children: [
              Container(
                color: Colors.grey[800],
                child: Row(
                  children: [
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(left: 10, bottom: 5),
                          child: Text(
                            widget.userNumber,
                            style: customTextStyle(18),
                          ),
                        ),
                        Padding(
                          padding: EdgeInsets.only(left: width / 39.2),
                          child: Text(
                            'sip: ' + widget.userNumber + '@' + widget.server,
                            style: const TextStyle(color: Colors.white),
                          ),
                        ),
                      ],
                    ),
                    const Spacer(),
                    Padding(
                      padding: const EdgeInsets.only(bottom: 5),
                      child: authStateWidget(
                          context,
                          '7221',
                          widget.server,
                          '',
                          width,
                          height), 
                    ),
                  ],
                ),
              ),



              ValueListenableBuilder(
                  valueListenable: listenListOfmessages,
                  builder: (context, List<ChatMessage> _chatRoomBox, _) {
                    return Expanded(
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: listenListOfmessages.value.length,
                        itemBuilder: (context, int index) {
                          final String chatMessage =
                              listenListOfmessages.value[index].message;
                          return ListTile(
                            leading: Text(chatMessage),
                          );
                        },
                      ),
                    );
                  }),
              IconButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  icon: const Icon(Icons.arrow_back)),

              Container(
                decoration: BoxDecoration(color: Colors.grey[900]),
                child: Padding(
                  padding: const EdgeInsets.only(left: 5, right: 5),
                  child: Row(
                    children: [
                      SizedBox(
                        width: width / 1.35,
                        child: Padding(
                          padding: EdgeInsets.only(
                              bottom: height / 40.1, left: width / 39.2),
                          child: TextField(
                            style: const TextStyle(color: Colors.white),
                            controller: _textController,
                            decoration: const InputDecoration(
                              hintText: 'Type to compose',
                              hintStyle: TextStyle(
                                  fontSize: 14.0, color: Colors.white),
                              enabledBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color: Colors.white),
                                  borderRadius: BorderRadius.only(
                                      bottomRight: Radius.zero)),
                            ),
                          ),
                        ),
                      ),
                      SizedBox(
                        width: width / 39.2,
                      ),
                      Expanded(
                        child: SizedBox(
                          width: width / 4.9,
                          child: ElevatedButton(
                            // style: ElevatedButton.styleFrom(
                            //     backgroundColor: Colors.grey[800]),
                            onPressed: () async {
                              MessageService().writeOutcomingMessage(
                                  ChatMessage(
                                      name: widget.userNumber,
                                      message: _textController.text,
                                      time: DateFormat('yyyy-MM-dd – kk:mm')
                                          .format(DateTime.now()),
                                      isSender: true,
                                      deliverStatus: 'sending..'),
                                  <String, String>{
                                    toNumber: widget.userNumber,
                                    message: _textController.text,
                                  });
                              _textController.clear();
                            },
                            child: const Text(
                              'Send',
                              style:
                                  TextStyle(fontSize: 16, color: Colors.white),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ));
  }

我想监听聊天消息列表中的更改,并在列表中出现新消息时调用 СhatScreen 重建。 我尝试在 СhatScreen 中创建另一个 ValueListenableBuilder 并仅监听列表中的更改,但我不知道如何访问此框字段。这里正确的方法是什么?

flutter dart hive
1个回答
0
投票

我有一个类似的实现。我已更改变量名称以匹配您自己的变量名称。看看吧

class ChatScreen extends StatelessWidget {
  final String chatRoomId;
  ChatScreen({super.key, required this.chatRoomId});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
        valueListenable: Hive.box<ChatRoom>('ChatRooms').listenable(keys: [chatRoomId]),
        builder: (context, box, _) {
          final chat = box.values.firstWhere((element) => element.id == chatRoomId);
          return Scaffold(
            appBar: AppBar(
                leading: BackButton(
                  onPressed: () => Get.back(),
                ),
                title: Text(chat.convoName)),
            body: Column(
              children: [
                Expanded(
                  child: ListView.builder(
                    itemCount: chat.messages.length,
                    itemBuilder: (context, index) {
                      final message = chat.messages[index];
                      return MessageWidget(message: message);
                    },
                  ),
                ),
                MessageInputWidget(
                  chatId: chatId,
                )
              ],
            ),
          );
        });
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.