Flutter即时通讯插件chat_flutter的使用

Flutter即时通讯插件chat_flutter的使用

1. 特性

这个工具组件可以显示聊天记录,通常用于显示聊天记录内容。显示的内容支持以下基本内容:

  • 图片 (image)
  • 文件 (file)
  • 文字 (text)
  • 音频 (audio)
  • 视频 (video)

2. 安装

您可以通过在 pubspec.yaml 文件中添加依赖来安装该插件。

dependencies:
  chat_flutter: ^3.0.0

或者通过终端命令安装:

flutter pub add chat_flutter

3. 使用

引入需要的页面:

import 'package:chat_flutter/chat_flutter.dart';

完整示例代码如下:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:chat_flutter/chat_flutter.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<ChatViewItem> chatRecordList = [];

  ChatViewWidgetController? _chatViewWidgetController;

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

    // 模拟从接口获取到数据
    _getListInfo();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: const Locale('zh'),
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate
      ],
      supportedLocales: const [Locale('zh', 'CH')],
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          // title: const Text('chat_flutter 插件展示案例'),
        ),
        backgroundColor: const Color.fromARGB(255, 239, 238, 234),
        body: Column(
          children: [
            Expanded(
              child: ChatViewWidget(
                isNeedScrollBottom: true, // 是否在初始渲染时滑动到底部
                isOpenPreviewImage: true, // 是否启用图片预览
                children: chatRecordList,
                onCreated: (chatViewWidgetListViewController, chatViewWidgetController) {
                  _chatViewWidgetController = chatViewWidgetController;
                  // 模拟发送消息
                  Future.delayed(const Duration(seconds: 3), () {
                    chatViewWidgetController.add(const ChatViewItem(
                      senderRight: false, // 是否在右侧显示
                      itemBodyType: ChatViewItemRecordBodyType.image, // 内容类型
                      itemBody: "https://pic35.photophoto.cn/20150511/0034034892281415_b.jpg", // 图片链接
                    ));
                  });
                },
              ),
            )
          ],
        ),
      ),
    );
  }

  /// 模拟接口请求
  void _getListInfo() {
    Future.delayed(const Duration(milliseconds: 1000), () {
      _chatViewWidgetController?.addAll([
        const ChatViewItem(
          itemBody: "hello",
        ),
        const ChatViewItem(
          senderRight: false,
          itemBody: "Hi",
        ),
        ChatViewItem(
          itemBody: "不显示头像",
          avatarModel: ChatViewItemAvatarModel(
            isAvatarShow: false, // 是否显示头像
          ),
          textTypeModel: ChatViewItemTextTypeModel(isOpenTextSelect: true), // 是否开启文本选择
        ),
        ChatViewItem(
          audioTypeModel: ChatViewItemAudioTypeModel(
            audioTimelength: 10, // 音频时长
          ),
          itemBodyType: ChatViewItemRecordBodyType.audio, // 内容类型为音频
        ),
        const ChatViewItem(
          senderRight: false,
          itemBody: "Hi, 就阿萨德理解啊睡了多久啊是 啊可是建档立卡上的结论是",
        ),
        const ChatViewItem(
          customItem: Text('自定义消息主体'), // 自定义消息主体
        ),
        ChatViewItem(
          textTypeModel: ChatViewItemTextTypeModel(
            isOpenTextSelect: true, // 是否开启文本选择
            createSelectableTextCallback: (focusNode) {
              // _focusNode = focusNode;
            },
          ),
          itemBody: "我是长按文字会出现菜单的文字",
        ),
        ChatViewItem(
          senderRight: false,
          avatarModel: ChatViewItemAvatarModel(
            avatarPath: "https://img1.baidu.com/it/u=3007048469,3759326707&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500",
          ),
          itemBodyRecordTime: '2023-12-13', // 记录时间
          itemBody: "带记录时间",
        ),
        ChatViewItem(
          itemBodyType: ChatViewItemRecordBodyType.image, // 内容类型为图片
          itemBody: "https://pic35.photophoto.cn/20150511/0034034892281415_b.jpg",
          imageTypeModel: ChatViewItemImageTypeModel(
            previewImageLongPressMenu: const ['保存'], // 预览图片长按菜单
            onPreviewImageTapMenu: (data, index, menuList) {
              debugPrint("$data $index $menuList");
            },
            // customPreviewImageCallback:(imagePath) {
            //     print(imagePath);
            // },
            // customLongPress:(context) {
            //     print('customLongPress');
            // },
          ),
        ),
        const ChatViewItem(
          itemBodyType: ChatViewItemRecordBodyType.video, // 内容类型为视频
          itemBody: "https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4",
          // videoTypeModel: ChatViewItemVideoTypeModel(
          //     videoLoadFailCallback: (error) {},
          //     notPlayingWidget: const Text('not Playing Widget'),
          //     playingFailWidget: const Text('playing Fail Widget'),
          //     autoPlaying: true,
          // ),
        ),
        const ChatViewItem(
          senderRight: false,
          itemBodyType: ChatViewItemRecordBodyType.image,
          itemBody: "https://img1.baidu.com",
        ),
        ChatViewItem(
          senderRight: false,
          avatarModel: ChatViewItemAvatarModel(
            avatarPath: "https://img1.baidu.com/it/u=3007048469,3759326707&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500",
          ),
          itemBody: "头像网络图片",
        ),
        ChatViewItem(
          avatarModel: ChatViewItemAvatarModel(
            avatarPath: "https://img1.baidu.com/it/u=30070484691,3759326707&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500",
          ),
          itemBody: "错误头像图片地址",
        ),
        ChatViewItem(
          avatarModel: ChatViewItemAvatarModel(
            avatarPath: "assets/logo.png",
          ),
          itemBody: "头像本地图片",
        ),
        const ChatViewItem(
          senderRight: false,
          itemBodyType: ChatViewItemRecordBodyType.image,
          itemBody: "https://img1.baidu.com/it/u=3007048469,3759326707&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500",
        ),
        const ChatViewItem(
          itemBodyType: ChatViewItemRecordBodyType.file, // 内容类型为文件
          itemBody: "我是文件名称",
        ),
      ]);
    });
  }
}

渲染效果

以下是插件的一些渲染效果图:

渲染效果图1 渲染效果图2 渲染效果图3 渲染效果图4 渲染效果图5

注意事项

  1. 该插件仅提供显示,并不提供功能实现。例如:当显示的记录内容为音频时,此插件并不实现音频播放功能,用户需要自行实现音频播放功能。

  2. 该插件不对内容的宽度或高度进行限制,因此需要使用 widget 包装插件并设置盒子的宽高。

  3. 如果在 release 模式下遇到渲染问题,请按照以下方式修改: 在项目根目录下的 project/android/app/build.gradle 文件中的 buildTypesrelease 模式下添加以下代码:

    buildTypes {
        release {
            signingConfig signingConfigs.debug
            // 添加以下代码
            shrinkResources false // 关闭代码混淆
            minifyEnabled false // 关闭资源缩减
        }
    }
    

插件模型适配

该插件本身基于 flutter_screenutil 插件进行了多种模型适配,因此您不必担心在使用过程中出现 UI 紊乱等问题。如果使用的模型没有正确适配导致 UI 样式混乱等问题,可以通过下方联系方式联系我提供帮助。

插件依赖问题

作者发现插件使用的依赖已经更新后会尽快更新,为了在使用过程中有更流畅的体验,建议您尽快更新插件,或在 pubspec.yaml 文件中版本号前加上 ^ 符号以使用最新版本的插件。

当前一些功能实现依赖以下插件:

  • flutter_screenutil
  • photo_view
  • video_player

自定义

该插件提供了高度自定义的功能,以便在您不满意提供的 UI 时能够自定义满足您的需求。

国际化

提示:插件本身涉及的固定文本内容(如提醒和显示)已适应语言环境。目前仅支持以下语言环境:

  • CH -> 中文 (默认)
  • US -> 英语

如果您需要切换和修改,请参考以下代码格式进行修改:

import 'package:flutter_localizations/flutter_localizations.dart';

[@override](/user/override)
Widget build(BuildContext context) {
    return MaterialApp(
        locale: const Locale('zh'),
        localizationsDelegates: const [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate
        ],
        supportedLocales: const [Locale('zh', 'CH')],
    );
}

更多关于Flutter即时通讯插件chat_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter即时通讯插件chat_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用chat_flutter插件的简单示例代码。请注意,chat_flutter可能并不是实际存在的官方插件名,因此以下示例代码是基于假设的一个即时通讯插件的使用方式。在实际使用中,请查阅具体插件的官方文档。

首先,确保你已经在pubspec.yaml文件中添加了chat_flutter依赖(假设该插件存在):

dependencies:
  flutter:
    sdk: flutter
  chat_flutter: ^latest_version  # 替换为实际版本号

然后,运行flutter pub get来获取依赖。

接下来,是一个基本的Flutter应用示例,展示如何使用chat_flutter插件来实现即时通讯功能。

import 'package:flutter/material.dart';
import 'package:chat_flutter/chat_flutter.dart';  // 假设chat_flutter提供了这个包路径

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

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

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

class _ChatScreenState extends State<ChatScreen> {
  late ChatController chatController;

  @override
  void initState() {
    super.initState();
    // 初始化ChatController,假设chat_flutter提供了这样的初始化方法
    chatController = ChatController(
      onNewMessage: (message) {
        // 处理新消息的逻辑,例如更新UI
        print('New message received: ${message.text}');
      },
      // 其他初始化参数...
    );

    // 连接到聊天服务器(假设chat_flutter提供了这样的方法)
    chatController.connectToServer('your_server_url');
  }

  @override
  void dispose() {
    // 断开与服务器的连接,释放资源
    chatController.disconnectFromServer();
    chatController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chat Screen'),
      ),
      body: ChatView(
        controller: chatController,
        // 假设ChatView是chat_flutter提供的用于显示聊天内容的组件
        onSendMessage: (text) {
          // 发送消息的逻辑
          chatController.sendMessage(text);
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 打开键盘输入消息(这里只是一个示例,实际可能由ChatView处理)
          // 通常ChatView会有自己的TextField来处理消息输入
        },
        tooltip: 'Send message',
        child: Icon(Icons.send),
      ),
    );
  }
}

// 假设ChatView是chat_flutter提供的组件,用于显示聊天内容
// 这里只是一个占位符,实际使用时请查阅chat_flutter的文档
class ChatView extends StatelessWidget {
  final ChatController controller;
  final ValueChanged<String> onSendMessage;

  ChatView({required this.controller, required this.onSendMessage});

  @override
  Widget build(BuildContext context) {
    // 这里应该包含显示消息列表和消息输入框的逻辑
    // 但由于chat_flutter是假设的插件,因此这里仅提供一个简单的占位实现
    return Column(
      children: <Widget>[
        Expanded(
          child: ListView.builder(
            // 显示消息列表的逻辑
            itemBuilder: (_, index) {
              // 假设controller.messages提供了消息列表
              // 这里应该根据消息类型(文本、图片等)来渲染不同的UI组件
              return Text('Message ${index + 1}');
            },
            itemCount: controller.messages.length,
          ),
        ),
        TextField(
          onSubmitted: onSendMessage,
          decoration: InputDecoration(
            labelText: 'Send a message',
          ),
        ),
      ],
    );
  }
}

// 假设ChatController是chat_flutter提供的控制器类,用于管理聊天逻辑
// 这里只是一个占位符,实际使用时请查阅chat_flutter的文档
class ChatController {
  List<Message> messages = [];

  ChatController({required VoidCallback onNewMessage}) {
    // 初始化逻辑,例如设置事件监听器等
  }

  void connectToServer(String url) {
    // 连接到聊天服务器的逻辑
  }

  void disconnectFromServer() {
    // 断开与服务器的连接
  }

  void sendMessage(String text) {
    // 发送消息的逻辑,例如将消息添加到messages列表并发送到服务器
    messages.add(Message(text: text));
    // 触发新消息事件
    // 假设存在一个方法用于触发onNewMessage回调
  }

  void dispose() {
    // 释放资源的逻辑
  }
}

// 假设Message是chat_flutter提供的消息类
// 这里只是一个占位符,实际使用时请查阅chat_flutter的文档
class Message {
  String text;

  Message({required this.text});
}

请注意,由于chat_flutter并不是实际存在的Flutter官方插件,因此上述代码中的类和方法(如ChatControllerChatViewconnectToServer等)都是假设的。在实际使用中,你需要查阅具体即时通讯插件的官方文档,并根据其提供的API来实现相应的功能。

回到顶部