Flutter聊天界面插件dash_chat的使用

Flutter聊天界面插件dash_chat的使用

更新信息

⚠️ Dashchat v2 的开发即将开始 ⚠️

v2 的第一个版本预计在1月发布。v1 仍然可以使用,但不会有任何额外的开发。如果需要在v2中实现或修复某些功能,可以在v1中打开问题进行反馈。

Dash Chat简介

💬 Dash Chat

The most complete Chat UI for flutter

Inspired by react-native-gifted-chat. Highly customizable and helps developing chat UI faster.

使用方法 💻

要使用此插件,在 pubspec.yaml 文件中添加 dash_chat 作为依赖项。

dependencies:
  dash_chat: ^4.1.0 # 确保使用最新版本

然后运行 flutter pub get 以安装依赖项。

功能 🔮

  • 完全可定制的组件
  • 复制消息到剪贴板
  • 多行文本输入框
  • 使用 flutter_parsed_text 的可点击链接
  • 作为用户首字母的头像
  • 快速回复消息
  • 加载早期消息
  • 滚动到底部的小部件
  • 发送器操作(例如附加照片等) - 正在开发中

消息对象 📦

示例:普通聊天消息

ChatMessage(
  text: "Hello",
  user: ChatUser(
    name: "Fayeed",
    uid: "123456789",
    avatar: "https://www.wrappixel.com/ampleadmin/assets/images/users/4.jpg",
  ),
  createdAt: DateTime.now(),
  image: "http://www.sclance.com/images/picture/Picture_753248.jpg",
);

示例:带快速回复的聊天消息

ChatMessage(
  text: "This is a quick reply example.",
  user: ChatUser(),
  createdAt: DateTime.now(),
  quickReplies: QuickReplies(
    values: [
      Reply(
        title: "😋 Yes",
        value: "Yes",
      ),
      Reply(
        title: "😞 Nope. What?",
        value: "no",
      ),
    ],
  ),
),

参数 ⚙️

基本参数

DashChat(
  user: ChatUser(
    name: "Jhon Doe",
    uid: "xxxxxxxxx",
    avatar: "https://www.wrappixel.com/ampleadmin/assets/images/users/4.jpg",
  ),
  onSend: onSend,
  alwaysShowSend: false,
  avatarMaxSize: 30.0,
  dateFormat: DateFormat('yyyy-MM-dd'),
  timeFormat: DateFormat('HH:mm:ss'),
  showUserAvatar: false,
  showAvatarForEveryMessage: false,
  onPressAvatar: (ChatUser user) {},
  onLongPressAvatar: (ChatUser user) {},
  onLongPressMessage: (ChatMessage message) {},
  inverted: false,
  avatarBuilder: (ChatUser user) {},
  messageBuilder: (ChatMessage message) {},
  messageTextBuilder: (String text) {},
  messageImageBuilder: (String imageUrl) {},
  messageTimeBuilder: (String time) {},
  dateBuilder: (String date) {},
  sendButtonBuilder: (Function onPressed) {},
  chatFooterBuilder: () {},
  inputFooterBuilder: () {},
  maxInputLength: null,
  parsePatterns: [
    MatchText(
      type: "email",
      onTap: (String value) {},
    ),
    MatchText(
      pattern: r"\B#+([\w]+)\b",
      style: TextStyle(
        color: Colors.pink,
        fontSize: 24,
      ),
      onTap: (String value) {},
    ),
  ],
  messageContainerDecoration: BoxDecoration(),
  leading: [],
  trailing: [],
  readOnly: false,
  showTraillingBeforeSend: true,
  inputTextStyle: TextStyle(),
  inputContainerStyle: BoxDecoration(),
  inputMaxLines: 1,
  showInputCursor: true,
  inputCursorWidth: 2.0,
  inputCursorColor: Colors.black,
  scrollController: ScrollController(),
  messageContainerPadding: EdgeInsets.zero,
  messagePadding: EdgeInsets.zero,
  onQuickReply: (Reply reply) {},
  quickReplyStyle: BoxDecoration(),
  quickReplyTextStyle: TextStyle(),
  quickReplyBuilder: (Reply reply) {},
  scrollToBottom: true,
  scrollToBottomStyle: ScrollToBottomStyle(),
  scrollToBottomWidget: () {},
  onScrollToBottomPress: () {},
  shouldShowLoadEarlier: false,
  showLoadEarlierWidget: () {},
  onLoadEarlier: () {},
  inputToolbarPadding: EdgeInsets.zero,
  inputToolbarMargin: EdgeInsets.zero,
  shouldStartMessagesFromTop: false,
  textBeforeImage: true,
  quickReplyScroll: false,
  quickReplyPadding: EdgeInsets.zero,
  inputDisabled: false,
  messageDecorationBuilder: (ChatMessage msg, bool isUser) {},
)

示例代码

以下是一个完整的示例代码,展示了如何使用 dash_chat 插件创建一个简单的聊天界面:

import 'dart:async';
import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:dash_chat/dash_chat.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.purple,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<DashChatState> _chatViewKey = GlobalKey<DashChatState>();

  final ChatUser user = ChatUser(
    name: "Fayeed",
    uid: "123456789",
    avatar: "https://www.wrappixel.com/ampleadmin/assets/images/users/4.jpg",
  );

  final ChatUser otherUser = ChatUser(
    name: "Mrfatty",
    uid: "25649654",
  );

  List<ChatMessage> messages = [];
  var m = [
    ChatMessage(
      text: "Hello there!",
      user: otherUser,
      createdAt: DateTime.now(),
    ),
    // 添加更多初始消息
  ];

  var i = 0;

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  void systemMessage() {
    Timer(Duration(milliseconds: 300), () {
      if (i < 6) {
        setState(() {
          messages = [...messages, m[i]];
        });
        i++;
      }
      Timer(Duration(milliseconds: 300), () {
        _chatViewKey.currentState!.scrollController
          ..animateTo(
            _chatViewKey.currentState!.scrollController.position.maxScrollExtent,
            curve: Curves.easeOut,
            duration: const Duration(milliseconds: 300),
          );
      });
    });
  }

  void onSend(ChatMessage message) {
    print(message.toJson());
    FirebaseFirestore.instance
        .collection('messages')
        .doc(DateTime.now().millisecondsSinceEpoch.toString())
        .set(message.toJson());

    setState(() {
      messages = [...messages, message];
    });

    if (i == 0) {
      systemMessage();
      Timer(Duration(milliseconds: 600), () {
        systemMessage();
      });
    } else {
      systemMessage();
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Chat App"),
      ),
      body: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore.instance
              .collection('messages')
              .orderBy("createdAt")
              .snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(
                  valueColor: AlwaysStoppedAnimation<Color>(
                    Theme.of(context).primaryColor,
                  ),
                ),
              );
            } else {
              List<DocumentSnapshot> items = snapshot.data!.docs;
              var messages =
                  items.map((i) => ChatMessage.fromJson(i.data()!)).toList();
              return DashChat(
                key: _chatViewKey,
                inverted: false,
                onSend: onSend,
                sendOnEnter: true,
                textInputAction: TextInputAction.send,
                user: user,
                inputDecoration:
                    InputDecoration.collapsed(hintText: "Add message here..."),
                dateFormat: DateFormat('yyyy-MMM-dd'),
                timeFormat: DateFormat('HH:mm'),
                messages: messages,
                showUserAvatar: false,
                showAvatarForEveryMessage: false,
                scrollToBottom: false,
                onPressAvatar: (ChatUser user) {
                  print("OnPressAvatar: ${user.name}");
                },
                onLongPressAvatar: (ChatUser user) {
                  print("OnLongPressAvatar: ${user.name}");
                },
                inputMaxLines: 5,
                messageContainerPadding: EdgeInsets.only(left: 5.0, right: 5.0),
                alwaysShowSend: true,
                inputTextStyle: TextStyle(fontSize: 16.0),
                inputContainerStyle: BoxDecoration(
                  border: Border.all(width: 0.0),
                  color: Colors.white,
                ),
                onQuickReply: (Reply reply) {
                  setState(() {
                    messages.add(ChatMessage(
                        text: reply.value,
                        createdAt: DateTime.now(),
                        user: user));
                    messages = [...messages];
                  });

                  Timer(Duration(milliseconds: 300), () {
                    _chatViewKey.currentState!.scrollController
                      ..animateTo(
                        _chatViewKey.currentState!.scrollController.position
                            .maxScrollExtent,
                        curve: Curves.easeOut,
                        duration: const Duration(milliseconds: 300),
                      );

                    if (i == 0) {
                      systemMessage();
                      Timer(Duration(milliseconds: 600), () {
                        systemMessage();
                      });
                    } else {
                      systemMessage();
                    }
                  });
                },
                onLoadEarlier: () {
                  print("loading...");
                },
                shouldShowLoadEarlier: false,
                showTraillingBeforeSend: true,
                trailing: [
                  IconButton(
                    icon: Icon(Icons.photo),
                    onPressed: () async {
                      final picker = ImagePicker();
                      PickedFile? result = await picker.getImage(
                        source: ImageSource.gallery,
                        imageQuality: 80,
                        maxHeight: 400,
                        maxWidth: 400,
                      );

                      if (result != null) {
                        final Reference storageRef =
                            FirebaseStorage.instance.ref().child("chat_images");

                        final taskSnapshot = await storageRef.putFile(
                          File(result.path),
                          SettableMetadata(
                            contentType: 'image/jpg',
                          ),
                        );

                        String url = await taskSnapshot.ref.getDownloadURL();

                        ChatMessage message =
                            ChatMessage(text: "", user: user, image: url);

                        FirebaseFirestore.instance
                            .collection('messages')
                            .add(message.toJson());
                      }
                    },
                  )
                ],
              );
            }
          }),
    );
  }
}

更多关于Flutter聊天界面插件dash_chat的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter聊天界面插件dash_chat的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用dash_chat插件来创建聊天界面的示例代码。dash_chat是一个功能强大的Flutter插件,适用于构建聊天界面。

首先,你需要在你的pubspec.yaml文件中添加dash_chat依赖:

dependencies:
  flutter:
    sdk: flutter
  dash_chat: ^1.1.20  # 请确保使用最新版本

然后运行flutter pub get来安装依赖。

接下来是一个完整的示例代码,展示了如何使用dash_chat来创建一个简单的聊天界面:

import 'package:flutter/material.dart';
import 'package:dash_chat/dash_chat.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Chat Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChatScreen(),
    );
  }
}

class ChatScreen extends StatefulWidget {
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final List<ChatMessage> messages = [
    ChatMessage(
      id: '1',
      sender: ChatUser(id: 'user1', name: 'Alice'),
      text: 'Hello!',
      createdAt: DateTime.now().subtract(Duration(minutes: 1)),
      type: MessageType.text,
    ),
    ChatMessage(
      id: '2',
      sender: ChatUser(id: 'user2', name: 'Bob'),
      text: 'Hi Alice!',
      createdAt: DateTime.now(),
      type: MessageType.text,
    ),
  ];

  final TextEditingController textController = TextEditingController();

  void sendMessage() {
    if (textController.text.isNotEmpty) {
      setState(() {
        messages.add(
          ChatMessage(
            id: messages.length.toString(),
            sender: ChatUser(id: 'user1', name: 'Alice'),
            text: textController.text,
            createdAt: DateTime.now(),
            type: MessageType.text,
          ),
        );
        textController.clear();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chat Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Expanded(
              child: DashChat(
                messages: messages,
                user: ChatUser(id: 'user1', name: 'Alice'),
                inputTextFieldHintText: 'Write a message...',
                onSend: (ChatMessage message) {
                  // Handle sending message logic here if needed
                  sendMessage();
                },
                scrollToBottom: true,
                showUserAvatar: true,
                showAvatarForEveryMessage: false,
                inputTextFieldController: textController,
                showSendButton: true,
                showInputTextField: true,
                inputMaxLines: 4,
                inputPadding: EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0),
                timeFormat: 'HH:mm',
                dateFormat: 'dd/MM/yyyy',
                isMessageReadReceiptEnabled: true,
                messageContainerStyle: MessageContainerStyle(
                  alignment: Alignment.centerLeft,
                ),
                inputContainerStyle: InputContainerStyle(
                  borderRadius: 30.0,
                ),
                bubble: Bubble(
                  alignment: Alignment.topLeft,
                  popBubble: true,
                  showTrailingIcon: true,
                  isSender: false,
                  tailWidth: 10.0,
                  tailHeight: 20.0,
                  tailColor: Colors.grey[300]!,
                  tailPosition: TailPosition.bottomRight,
                  containerPadding: EdgeInsets.all(8.0),
                  textStyle: TextStyle(color: Colors.black),
                  containerDecoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(15.0),
                  ),
                ),
                inputTextStyle: TextStyle(fontSize: 16.0),
                sendButtonTextStyle: TextStyle(fontSize: 16.0),
                sendButtonIcon: Icon(
                  Icons.send,
                  color: Colors.white,
                ),
                sendButtonContainerStyle: ContainerStyle(
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    borderRadius: BorderRadius.circular(30.0),
                  ),
                  padding: EdgeInsets.all(10.0),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

这个示例代码展示了如何设置DashChat组件,包括:

  • 显示消息列表
  • 输入文本字段
  • 发送按钮
  • 自定义气泡样式
  • 滚动到底部的新消息

你可以根据需要进一步自定义和扩展这个示例,比如添加图片消息、视频消息、文件上传等功能。dash_chat插件提供了丰富的配置选项,可以满足大多数聊天应用的需求。

回到顶部