TUIKit 是基于 IM SDK 的一款 UI 组件库,可通过 UI 组件快速实现聊天、会话、搜索、关系链、群组等功能。本文介绍如何快速集成 TUIKit 并实现核心功能。
注意:
为了尊重版权,IM Demo/TUIKit 工程中默认不包含大表情元素切图。正式上线商用前请您替换为自己设计或拥有版权的其他表情包。下图所示默认的小黄脸表情包版权归腾讯云所有,可有偿授权使用,如需获得授权,您可以通过升级至 IM 企业版套餐 免费使用该表情包。


前提条件
Flutter >= 3.29.0 版本,Dart >= 3.7.0 版本。
Android Studio Dolphin | 2021.3.1 及以上版本,Android Gradle plugin 7.3.1 以上版本。
Xcode 12.0 及以上版本。
一个有效的腾讯云账号及 Chat 应用。可参考 开通服务 从控制台获取以下信息:
SDKAppID:App 在控制台获取的 Chat 应用的 ID,为应用的唯一标识。
SDKSecretKey:应用的密钥。
版本兼容性说明:
为确保构建环境稳定,请严格遵循官方兼容性要求进行配置:
Gradle、Android Gradle Plugin、JDK 与 Android Studio 的兼容性,请参阅 Android 官方文档:版本说明。
Kotlin、Android Gradle Plugin 与 Gradle 的版本对应关系,请参阅 Kotlin 官方文档:Kotlin-Gradle 插件兼容性。
Android Studio 安装时如果默认使用的 JDK 版本比较高可能会编译失败,建议使用 JDK 17 版本,请参阅:Java 版本切换。
我们建议您根据上述指南,选择与项目要求完全匹配的版本组合。
集成 TUIKit
1. 请参见 Flutter 文档 快速创建一个 Flutter 应用。
2. 在项目根目录执行如下命令安装依赖:
flutter pub add tencent_cloud_chat_uikitflutter pub add tencent_cloud_chat_sdk
3. 配置权限。
由于 TUIKit 运行,需要拍摄/相册/录音/网络等权限,需要您在 Native 的文件中手动声明,才可正常使用相关能力。
<!-- 打开 android/app/src/main/AndroidManifest.xml ,添加如下权限: --><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32" /><uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /><!-- Compatibility for Android13 --><uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
# 1、打开 ios/Podfile ,在文件末尾新增如下权限代码。post_install do |installer|installer.pods_project.targets.each do |target|flutter_additional_ios_build_settings(target)target.build_configurations.each do |config|config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'config.build_settings['ENABLE_BITCODE'] = 'NO'config.build_settings["ONLY_ACTIVE_ARCH"] = "NO"endtarget.build_configurations.each do |config|config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)','PERMISSION_MICROPHONE=1','PERMISSION_CAMERA=1','PERMISSION_PHOTOS=1',]endendend# 2、打开 ios/Runner/info.plist,添加权限描述 key<key>NSCameraUsageDescription</key><string>Our app requires access to your camera to enable video calling and capturing photos or videos to share in your conversations.</string><key>NSMicrophoneUsageDescription</key><string>Our app requires access to your microphone to enable voice and video calling features.</string><key>NSPhotoLibraryUsageDescription</key><string>Our app requires access to your photo library to enable sharing photos, videos, and files in your conversations.</string>
说明:
接入步骤
常用的聊天软件都是由会话列表、聊天窗口、好友列表、音视频通话等几个基本的界面组成,参考下面步骤,您仅需几行代码即可在项目中快速搭建这些 UI 界面。
步骤1:配置用户鉴权

步骤2:用户登录
/// main.dartimport 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();_coreInstance.init(sdkAppID: 0, // Replace 0 with the SDKAppID of your IM application when integrating// language: LanguageEnum.en, // 界面语言配置,若不配置,则跟随系统语言loglevel: LogLevelEnum.V2TIM_LOG_DEBUG,onTUIKitCallbackListener: (TIMCallback callbackValue){}, // [建议配置,详见此部分](https://cloud.tencent.com/document/product/269/70746#callback)listener: V2TimSDKListener());
您可以调用 login 接口,传入上文获取的 userSig 用于登录鉴权。登录鉴权后才能正常使用组件的功能。
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();_coreInstance.login(userID: userID, userSig: userSig);
注意:
步骤3:构建会话列表界面
会话列表通常作为 IM 应用的首页,展示所有单聊和群聊记录。
您需要创建一个 Conversation 类,使用
TIMUIKitConversation 组件渲染列表。关键逻辑在于 onTapItem 回调:当用户点击某一行会话时,SDK 会返回一个 selectedConv 对象,我们需要将其传递给下一页(聊天页面)。import 'package:flutter/material.dart';import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';class Conversation extends StatelessWidget {const Conversation({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Message",style: TextStyle(color: Colors.black),),),body: TIMUIKitConversation(onTapItem: (selectedConv) {// 如果需要适配桌面端,此处需要参考 Demo 代码修改。Navigator.push(context,MaterialPageRoute(builder: (context) => Chat(selectedConversation: selectedConv,),));},),);}}
步骤4:构建聊天界面
聊天界面用于接收上一步传递的会话信息,并渲染消息界面。
您需要创建一个 Chat 类,并定义一个 selectedConversation 参数来接收从列表页传来的数据。在 body 中使用
TIMUIKitChat 组件,直接将接收到的会话对象传入即可完成初始化。场景 1:从会话列表跳转进入(常规场景)
示例代码:
import 'package:flutter/material.dart';import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';class Chat extends StatelessWidget {final V2TimConversation selectedConversation;const Chat({Key? key, required this.selectedConversation}) : super(key: key);String? _getConvID() {return selectedConversation.type == 1? selectedConversation.userID: selectedConversation.groupID;}@overrideWidget build(BuildContext context) {return TIMUIKitChat(conversation: selectedConversation,onTapAvatar: (_, _) {// 如果需要适配桌面端,此处需要参考 Demo 代码修改。Navigator.push(context,MaterialPageRoute(builder: (context) => UserProfile(userID: userID),));}, // Callback for the clicking of the message sender profile photo. This callback can be used with `TIMUIKitProfile`.);}
场景 2:非列表跳转(自定义场景)
如果您的聊天页面并非由会话列表(Conversation)跳转进入,则无法直接获取
selectedConversation 对象。此时,您需要手动构造 V2TimConversation 实例并传入 TIMUIKitChat。TIMUIKitChat(conversation: V2TimConversation(conversationID: "c2c_10040818", // 单聊:"c2c_${对方的userID}" ; 群聊:"group_${groupID}"userID: "", // 仅单聊需要此字段,对方userIDgroupID: "", // 仅群聊需要此字段,群groupIDshowName: "", // 顶部 AppBar 显示的标题type: 1, // 单聊传1,群聊传2// 以上是最简化最基础的必要配置,您还可在此指定更多参数配置,根据 V2TimConversation 的注释),// ......其他 TIMUIKitChat 的配置参数);
步骤5:构建联系人界面
联系人界面展示用户的好友列表、群组列表、黑名单列表和新好友申请。
注意,下面代码只能将
TIMUIKitContact 初始化并展示出来,其中的点击行为(例如点击好友等),TUIKit 会通过 onTapItem, TopListItem 的 onTap 抛给上层处理:import 'package:flutter/material.dart';import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';class Contact extends StatelessWidget {const Contact({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Contact",style: TextStyle(color: Colors.black),),),body:TIMUIKitContact(topList: [TopListItem(name: "New Contact",id: "newContact",onTap: () {}),TopListItem(name: "My Groups",id: "groupList",onTap: () {}),TopListItem(name: "BlackList",id: "blackList",onTap: () {}),],onTapItem: (item) {Navigator.push(context,MaterialPageRoute(builder: (context) => UserProfile(userID: item.userID),));},),);}}
此时,您的应用已经可以完成消息收发,管理好友关系,展示用户详情及展示会话列表。
步骤6:构建音视频通话功能(可选)
TUI 组件支持在聊天界面对用户发起音视频通话,仅需要简单几步就可以快速集成:
视频通话 | 语音通话 |
![]() | ![]() |
1. 开通音视频服务。
2. 登录 即时通信 IM 控制台 ,单击目标应用卡片,进入应用的基础配置页面。
3. 在开通腾讯实时音视频服务功能区,单击免费体验即可开通 TUICallKit 的 7 天免费试用服务。
4. 在弹出的开通实时音视频 TRTC 服务对话框中,单击确认,系统将为您在 实时音视频控制台 创建一个与当前 IM 应用相同 SDKAppID 的实时音视频应用,二者账号与鉴权可复用。
5. 集成 TUICallKit 组件。
在 pubspec.yaml 文件中添加以下内容。
tencent_calls_uikit: ^2.9.1
6. 发起和接收视频或语音通话。
消息页发起通话 | 联系人页发起通话 |
![]() | ![]() |
集成 TUICallKit 组件后,聊天界面和联系人资料界面默认会出现 “视频通话” 和 “语音通话” 两个按钮,当用户点击按钮时,TUIKit 会自动展示通话邀请 UI,并给对方发起通话邀请请求。
当用户在线收到通话邀请时,TUIKit 会自动展示通话接收 UI,用户可以选择同意或者拒绝通话。
当用户离线收到通话邀请时,如果需要唤起 App 通话,就要使用到离线推送能力,离线推送的实现请参见 添加离线推送。
7. 添加离线推送。
8. 关于 App 的配置,您可以参见文档:集成推送服务(Push)跑通离线推送功能。
说明:
配置完成后,当单击接收到的音视频通话离线推送通知时, TUICallKit 会自动拉起音视频通话邀请界面。
常见问题
Android 端报错 compileSdkVersion 不合适怎么办?
1. 请在您项目的
pubspec.yaml 文件中,指定确保如下两个插件的版本。video_thumbnail: ^0.5.3permission_handler: ^10.0.0flutter_local_notifications: 9.7.0
2. 修改
android/app/build.gradle 文件,保证 android => compileSdkVersion 33。android {compileSdkVersion 33...}
3. 执行如下命令,重新安装 Android 端依赖。
flutter pub cache cleanflutter pub get
在 Flutter 2.x 上,Android 构建报错 Codepoint 984472 not found in font, aborting. 怎么办?


在您的编译命令中,加入
--no-tree-shake-icons。如:flutter build apk --no-tree-shake-icons --dart-define=SDK_APPID={您的SDKAPPID}
Flutter V1 UIKit Demo,选择 Android 平台运行 报如下错误:FAILURE: Build failed with an exception.
FAILURE: Build failed with an exception.* What went wrong:Could not open cp_settings generic class cache for settings file 'E:\\FlutterProject\\WorkProjects\\v1_demo_and_uikit\\v1_chat-demo-flutter\\android\\settings.gradle' (C:\\Users\\Administrator\\.gradle\\caches\\8.1.1\\scripts\\5f461bs4vludhoc0tr427ffwx).> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 65* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 1s
原因:
Unsupported class file major version 65(版本 65 对应的是 Java 21(Java 每个版本都有一个 class 文件版本号))。
项目使用了过旧的 Gradle 版本或系统安装了高于项目支持的 Java 版本。
解决方法:
在项目的
android/gradle.properties 文件中添加:org.gradle.java.home=您的 JDK 路径(建议使用 jdk17)。示例:
Windows:
org.gradle.java.home=C\\:\\\\Program Files\\\\Java\\\\jdk-17.0.2macOS/Linux:
org.gradle.java.home=/Users/xxxx/Downloads/jdk-17.0.2.jdk/Contents/Home iOS 端 Pods 依赖无法安装成功怎么办?
尝试方案一:配置运行后,如果报错,可以单击 Product > Clean Build Folder,清除产物后重新 pod install 或 flutter run


尝试方案二:手动删除 ios/Pods 文件夹,及 ios/Podfile.lock 文件,并执行如下命令,重新安装依赖
1. 搭载新款 Apple Silicon 的Mac设备,例如 M1。

cd iossudo arch -x86_64 gem install ffiarch -x86_64 pod install --repo-update
2. 搭载老款 Intel 芯片的 Mac 设备。
cd iossudo gem install ffipod install --repo-update
佩戴 Apple Watch 时,真机调试 iOS 报错怎么办?


请将您的 Apple Watch 调整至飞行模式,并将 iPhone 的蓝牙功能通过
设置 => 蓝牙 彻底关闭。重新启动 Xcode(若打开),并重新
flutter run 即可。Flutter 环境问题如何确认?
如您需得知 Flutter 的环境是否存在问题,请运行 Flutter doctor 检测 Flutter 环境是否装好。
使用 Flutter 自动生成的项目,引入 TUIKit 后,运行 Android 端报错怎么办?


1. 打开
android\\app\\src\\main\\AndroidManifest.xml,根据如下,补全 xmlns:tools="http://schemas.android.com/tools" / android:label="@string/android_label" 及 tools:replace="android:label"。<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="替换成您的 Android 端包名"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:label="@string/android_label"tools:replace="android:label"android:icon="@mipmap/ic_launcher" // 指定一个 icon 路径android:usesCleartextTraffic="true"android:requestLegacyExternalStorage="true">
2. 打开
android\\app\\build.gradle,补全 defaultConfig 中 minSdkVersion 及 targetSdkVersion。defaultConfig {applicationId "" // 替换成您的Android端包名minSdkVersion 21targetSdkVersion 30}
如何国际化界面语言?
如何获取 API 接口调用报错/Flutter 层报错/弹窗提示信息?
请在初始化 TUIKit 时,挂载
onTUIKitCallbackListener 监听。该监听用于返回包括:SDK API 错误 / Flutter 报错 / 一些可能需要弹窗提示用户的场景信息。
通过
TIMCallbackType确定类型。示例代码如下。您可以根据您的业务需要,修改以下代码,自定义提醒用户的逻辑,包括但不限于弹窗/横幅等。
final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();final isInitSuccess = await _coreInstance.init(onTUIKitCallbackListener: (TIMCallback callbackValue){switch(callbackValue.type) {case TIMCallbackType.INFO:// Shows the recommend text for info callback directlyUtils.toast(callbackValue.infoRecommendText!);break;case TIMCallbackType.API_ERROR://Prints the API error to console, and shows the error message.print("Error from TUIKit: ${callbackValue.errorMsg}, Code: ${callbackValue.errorCode}");if (callbackValue.errorCode == 10004 && callbackValue.errorMsg!.contains("not support @all")) {Utils.toast(imt("当前群组不支持@全体成员"));}else{Utils.toast(callbackValue.errorMsg ?? callbackValue.errorCode.toString());}break;case TIMCallbackType.FLUTTER_ERROR:default:// prints the stack trace to console or shows the catch errorif(callbackValue.catchError != null){Utils.toast(callbackValue.catchError.toString());}else{print(callbackValue.stackTrace);}}},);
下面,分别介绍这三种类型的回调:
SDK API 错误(TIMCallbackType.API_ERROR)
该场景下,提供 SDK API 原生
errorMsg及errorCode。Flutter 报错(TIMCallbackType.FLUTTER_ERROR)
该错误由监听 Flutter 原生抛出异常产生,提供错误发生时的
stackTrace(来自FlutterError.onError)或catchError(来自 try-catch)。场景信息(TIMCallbackType.INFO)
建议根据实际情况,将这些信息弹窗提示用户。
具体提示规则和弹窗样式可由您决定。
提供
infoCode场景码帮助您确定当前的场景,及默认的提示推荐语infoRecommendText。您可直接弹窗提示我们的推荐语,也可根据场景码自定义推荐语。推荐语语言使用系统语言或您指定的语言,请勿根据推荐语来判断场景。
场景码规则如下:
场景码由七位数组成,前五位数确定场景发生的组件,后两位确定具体的场景表现。
场景码开头 | 对应的组件 |
66601 | TIMUIKitAddFriend |
66602 | TIMUIKitAddGroup |
66603 | TIMUIKitBlackList |
66604 | TIMUIKitChat |
66605 | TIMUIKitContact |
66606 | TIMUIKitConversation |
66607 | TIMUIKitGroup |
66608 | TIMUIKitGroupProfile |
66609 | TIMUIKitNewContact |
66610 | TIMUIKitGroupProfile |
66611 | TIMUIKitNewContact |
66612 | TIMUIKitProfile |
66613 | TIMUIKitSearch |
66614 | 通用组件 |
全部场景码清单如下:
场景码 infoCode | 推荐提示语 infoRecommendText | 场景描述 |
6660101 | 好友申请已发送 | 用户申请添加其他用户为联系人 |
6660102 | 该用户已是好友 | 用户申请添加其他已是好友的用户为好友时,触发 onTapAlreadyFriendsItem 回调 |
6660201 | 群申请已发送 | 用户申请加入需要管理员审批的群聊 |
6660202 | 您已是群成员 | 用户申请加群时,判断用户已经是当前群成员,触发 onTapExistGroup 回调 |
6660401 | 无法定位到原消息 | 当用户需要跳转至@消息或者是引用消息时,在消息列表中查不到目标消息 |
6660402 | 视频保存成功 | 用户在消息列表,点开视频消息后,选择保存视频 |
6660403 | 视频保存失败 | 用户在消息列表,点开视频消息后,选择保存视频 |
6660404 | 说话时间太短 | 用户发送了过短的语音消息 |
6660405 | 发送失败,视频不能大于 100MB | 用户试图发送大于 100MB 的视频 |
6660406 | 图片保存成功 | 用户在消息列表,点开图片大图后,选择保存图片 |
6660407 | 图片保存失败 | 用户在消息列表,点开图片大图后,选择保存图片 |
6660408 | 已复制 | 用户在弹窗内选择复制文字消息 |
6660409 | 暂未实现 | 用户在弹窗内选择非标功能 |
6660410 | 其他文件正在接收中 | 用户点击下载文件消息时,前序下载任务还未完成 |
6660411 | 正在接收中 | 用户点击下载文件消息 |
6660412 | 视频消息仅限 mp4 格式 | 用户发送了一条非 mp4 格式的视频消息 |
6660413 | 已加入待下载队列,其他文件下载中 | 已加入待下载队列,其他文件下载中 |
6660414 | 正在下载中 | 桌面端图片/视频资源正在下载中,暂时无法打开,过一会下载好了才能打开 |
6660415 | 视频文件异常 | 发送的视频文件资源本身是错误或被损坏,无法发送 |
6661001 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改群资料 |
6661002 | 无网络连接,无法查看群成员 | 当用户试图在无网络环境下,修改群资料 |
6661003 | 成功取消管理员身份 | 用户将群内其他用户移除管理员 |
6661201 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改自己或联系人的资料 |
6661202 | 好友添加成功 | 在资料页添加其他用户为好友,并自动添加成功,无需验证 |
6661203 | 好友申请已发出 | 在资料页添加其他用户为好友,对方设置需要验证 |
6661204 | 当前用户在黑名单中 | 在资料页添加其他用户为好友,对方在自己的黑名单内 |
6661205 | 好友添加失败 | 在资料页添加其他用户为好友,添加失败,可能是由于对方禁止加好友 |
6661206 | 好友删除成功 | 在资料页删除其他用户为好友,成功 |
6661207 | 好友删除失败 | 在资料页删除其他用户为好友,失败 |
6661401 | 输入不能为空 | 当用户在录入信息时,输入了空字符串 |
6661402 | 请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法 | 用户退出群或解散群时,未提供返回首页办法 |
6661403 | 设备存储空间不足,建议清理,以获得更好使用体验 | 在 login 成功后,会自动检测设备存储空间,如果不足1GB,会提示存储空间不足 |



