Feedback

Android(Compose)

组件概述

MessageInput 是基于 Jetpack Compose 构建的消息输入组件,为用户提供完整的消息编辑和发送功能。该组件支持文本(含表情、群聊 @ 提及)、语音、图片、视频、文件等消息的输入和发送,支持引用回复,并可以在“更多”面板中发起音视频通话。组件支持多种样式配置,也支持自定义“更多”面板中的操作项。
消息输入界面
表情选择器



组件集成

MessageInput 组件属于 TUIKit Compose 的一部分,集成 TUIKit Compose 即可获取并使用 MessageInput 组件。集成方法请参考文档 TUIKit Compose 里的集成步骤。

组件构成

MessageInput 组件包含消息输入核心组件和配置协议 MessageInputConfigProtocol,提供了消息输入功能,并支持自定义。

对外方法

方法名
参数
描述
MessageInput
conversationID: String
会话 ID,用于标识当前聊天会话。如果是单聊,组成方式为 c2c_userID。如果是群聊,组成方式为 group_groupID。
modifier: Modifier
Jetpack Compose 中用来设置组件的样式、布局、行为和外观。
config: MessageInputConfigProtocol
输入框配置,控制各功能入口的显示、@ 提及、已读回执、录音时长,以及“更多”面板中的操作项。默认值为 ChatMessageInputConfig()。
messageInputViewModelFactory: MessageInputViewModelFactory
创建组件内部 MessageInputViewModel 的工厂类。通常情况下,您无需手动创建,组件已提供默认实现。
typingStatusSender: ((Boolean) -> Unit)?
输入状态回调,选填。用户编辑文字时回调输入框是否有内容,发送消息后回调 false。通常传入 MessageListController 的 sendTypingStatus,向对方发送“正在输入”状态,详见 MessageList 组件文档中的“与 MessageInput 组合使用”。

基础用法

MessageInput 组件可直接初始化使用,需要提供会话 ID。如需与消息列表组合成完整的聊天页面,请参见 MessageList 组件文档中的“与 MessageInput 组合使用”。
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import io.trtc.tuikit.chat.uikit.components.messageinput.ui.MessageInput

@Composable
fun MessageInputScreen(conversationID: String) {
Box(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding(),
contentAlignment = Alignment.BottomCenter
) {
MessageInput(conversationID = conversationID)
}
}
说明:
示例工程(demo)中提供了基于 ChatPage 封装好的聊天页 ChatActivity(带标题栏、未读角标、群事件处理等),可直接复用或参考其实现进行自定义:ChatActivity.start(context, conversationID)。

自定义组件

您可以自定义输入栏上的功能入口,以及“更多”面板中的操作项。方法如下。

自定义功能入口

通过 ChatMessageInputConfig 设置输入框的功能。ChatMessageInputConfig 的构造参数均为可选的命名参数,未设置的属性使用默认值:
属性名
类型
描述
isShowAudioRecorder
Boolean
是否显示输入栏左侧的语音按钮,点击后切换为“按住说话”模式。默认值为 true。
enableLongPressToTalk
Boolean
是否支持长按输入框录音(输入框为空且键盘、面板均收起时生效)。关闭后,输入框的提示文字由“发消息或按住说话...”变为“发消息...”。默认值为 true。
isShowEmoji
Boolean
是否显示表情按钮。默认值为 true。
isShowMore
Boolean
是否显示“更多”按钮。输入框中有文字时,该位置显示为发送按钮。默认值为 true。
isShowPhotoTaker
Boolean
是否在“更多”面板中显示“拍照”和“摄像”。默认值为 true。
isShowVideoCall
Boolean
是否在“更多”面板中显示“视频通话”。默认值为 true。
isShowAudioCall
Boolean
是否在“更多”面板中显示“语音通话”。默认值为 true。
enableMention
Boolean
是否支持在群聊中输入 @ 时弹出群成员选择列表。默认值为 true。
enableReadReceipt
Boolean
发送的消息是否请求已读回执,社群中不生效。需要配合 MessageList 的 isShowReadReceipt 展示已读状态。默认值为 false。
audioMaxRecordDurationMs
Int
单条语音的最长录制时长,单位为毫秒,小于 2000 时按 2000 处理。默认值为 60000。
例如,隐藏语音输入,或者隐藏输入栏上的全部功能入口:
import io.trtc.tuikit.chat.uikit.components.messageinput.config.ChatMessageInputConfig
import io.trtc.tuikit.chat.uikit.components.messageinput.ui.MessageInput

// 隐藏语音输入
MessageInput(
conversationID = conversationID,
config = ChatMessageInputConfig(
isShowAudioRecorder = false, // 隐藏语音按钮
enableLongPressToTalk = false // 关闭长按输入框录音
)
)

// 隐藏输入栏上的全部功能入口
MessageInput(
conversationID = conversationID,
config = ChatMessageInputConfig(
isShowAudioRecorder = false, // 隐藏语音按钮
enableLongPressToTalk = false, // 关闭长按输入框录音
isShowEmoji = false, // 隐藏表情按钮
isShowMore = false // 隐藏更多按钮
)
)
注意:
isShowAudioRecorder 只控制语音按钮的显示。隐藏语音按钮后,用户仍然可以长按输入框录音,如需完全关闭语音输入,请同时将 enableLongPressToTalk 设为 false。
自定义效果如下图所示:
默认输入框
隐藏输入框上的语音录制功能



编辑“更多”面板操作项

点击输入栏上的“更多”按钮会展开“更多”面板。面板每页展示 4 列 × 2 行,操作项超过 8 个时可以左右滑动翻页。默认操作项依次为:
操作项
ID
描述
图片
MessageInputActionIDs.ALBUM
从相册选择图片或视频发送。
拍照
MessageInputActionIDs.TAKE_PHOTO
拍照并发送。isShowPhotoTaker 为 false 时不展示。
摄像
MessageInputActionIDs.RECORD_VIDEO
录制视频并发送。isShowPhotoTaker 为 false 时不展示。
文件
MessageInputActionIDs.FILE
选择文件发送。
视频通话
MessageInputActionIDs.VIDEO_CALL
发起视频通话。isShowVideoCall 为 false 时不展示。
语音通话
MessageInputActionIDs.AUDIO_CALL
发起语音通话。isShowAudioCall 为 false 时不展示。
通过 ChatMessageInputConfig 的 customizeActions 编辑“更多”面板中的操作项。在 customizeActions 中,可以通过 editorContext.conversationID 获取当前会话 ID,通过 editorContext.androidContext 获取 Android Context,并调用以下方法编辑操作项:
方法
描述
add(item)
在末尾添加操作项。item 的 ID 为空白或与已有操作项重复时会抛出 IllegalArgumentException。
remove(ID)
移除指定 ID 的操作项,不存在时返回 false。
replace(ID) { item -> ... }
替换指定 ID 的操作项,不存在时返回 false。替换后的操作项必须保持 ID 不变,否则会抛出异常。
insertBefore(anchorID, item) / insertAfter(anchorID, item)
在锚点操作项之前或之后插入操作项。锚点不存在时返回 false,且不会插入。item 的 ID 规则与 add 相同。
moveBefore(ID, anchorID) / moveAfter(ID, anchorID)
将操作项移动到锚点操作项之前或之后,任意一个 ID 不存在时返回 false。
clear()
移除全部操作项。
items
当前操作项列表的只读快照。
操作项 MessageInputMenuAction 的字段说明如下:
字段
类型
描述
ID
String
操作项的唯一标识,必填。
title
String
操作项标题。
iconResID
Int
操作项图标的 drawable 资源 ID。必须设置为有效的资源 ID,否则会导致崩溃。图标会按主题的文字颜色着色,建议使用单色图标。
onClick
() -> Unit
点击操作项时的回调。
showRedDot
Boolean
是否在操作项上显示红点,默认为 false。有操作项显示红点时,“更多”按钮上也会显示红点。
dangerous
Boolean
是否为危险操作,默认为 false。目前不影响“更多”面板的显示样式。
示例代码如下:
import android.content.Context
import io.trtc.tuikit.chat.uikit.components.messageinput.config.ChatMessageInputConfig
import io.trtc.tuikit.chat.uikit.components.messageinput.data.MessageInputActionIDs
import io.trtc.tuikit.chat.uikit.components.messageinput.data.MessageInputMenuAction
import io.trtc.tuikit.chat.uikit.components.messageinput.ui.MessageInput

val messageInputConfig = ChatMessageInputConfig(
isShowPhotoTaker = false // 不展示“拍照”和“摄像”
).customizeActions {
val androidContext = editorContext.androidContext
// 移除“文件”
remove(MessageInputActionIDs.FILE)
// 在末尾新增“位置”
add(
MessageInputMenuAction(
ID = "custom.messageInput.location",
title = "位置",
iconResID = android.R.drawable.ic_menu_mylocation,
onClick = {
// 选择位置并发送,editorContext.conversationID 为当前会话 ID
}
)
)
// 给“视频通话”加上红点,用户点击过后不再展示
val prefs = androidContext.getSharedPreferences("red_dot", Context.MODE_PRIVATE)
if (!prefs.getBoolean(MessageInputActionIDs.VIDEO_CALL, false)) {
replace(MessageInputActionIDs.VIDEO_CALL) { action ->
action.copy(
showRedDot = true,
onClick = {
prefs.edit().putBoolean(MessageInputActionIDs.VIDEO_CALL, true).apply()
action.onClick()
}
)
}
}
}

MessageInput(conversationID = conversationID, config = messageInputConfig)
注意:
customizeActions 中的代码会在每次展开“更多”面板时重新执行。用户点击带红点的操作项后,红点只在本次展开期间隐藏,如需让红点不再出现,请像示例一样自行记录点击状态。