跳到主要内容

输入区域

自定义输入框按钮UI

1.5.1 版本开始,IMKit 支持配置会话页面输入框的 UI 组件。可通过 setInputAreaComponentConfig 接口设置自定义组件配置。

接口定义

TypeScript
setInputAreaComponentConfig(componentConfig: InputAreaComponentConfig): void;

参数说明

InputAreaComponentConfig

参数名类型必填说明支持版本
identifierComponentIdentifier组件标识,指定要自定义的组件类型。详见下方"支持的组件类型"1.5.1
componentWrappedBuilder<[InputAreaComponentData]>自定义组件构建器,用于构建自定义 UI 组件1.6.0

InputAreaComponentData

参数名类型说明支持版本
contextContext应用上下文对象1.6.0
convIdConversationIdentifier会话标识对象1.6.0
datastring透传参数。当 identifierInputBarVoiceButton 时,值为 "Voice"(语音类型)或 "Text"(文本类型);当 identifierInputBarEmoticonButton 时,值为 "Emoticon"(表情类型)或 "Text"(文本类型);当 identifierDestructBarVoiceButton 时,值为 "Voice"(语音类型)或 "Text"(文本类型)1.6.0

支持的组件类型

identifier 支持的组件类型说明:

组件类型说明
InputBarVoiceButton输入框左侧语音按钮
InputBarEmoticonButton输入框表情按钮
InputBarSendButton输入框发送按钮
InputBarPluginButton输入框插件加号按钮
InputBarExpandTextAreaButton文本输入组件输入了大于 2 行文本时,输入框左侧的展开输入按钮
EmoticonBoardAddButton表情面板左下角的添加按钮

示例代码

TypeScript
// 设置接口
let InputBarPluginButton: InputAreaComponentConfig = {
identifier: ComponentIdentifier.InputBarPluginButton,
component: wrapBuilder(buildCustomInputBarPluginView),
}
RongIM.getInstance().conversationService().setInputAreaComponentConfig(InputBarPluginButton)

// 组件
@Builder
export function buildCustomInputBarPluginView(componentData: InputAreaComponentData) {
CustomInputBarPluginView({ context: componentData.context, convId: componentData.convId, type: componentData.data })
}

@Component
export struct CustomInputBarPluginView {
@Prop context: Context;
@Prop convId: ConversationIdentifier;
@Prop type: string;

aboutToAppear(): void {
console.log("CustomInputBarPluginView aboutToAppear " + this.type)
}

build() {
Image($r('app.media.default_fmessage'))
.size({ width: 30, height: 30 })
.onTouch(() => {
promptAction.showToast({ message: `点击了按钮` })
})
}
}

增加 + 号扩展栏插件

内置插件说明

IMKit 内置插件列表如下所示。其中位置插件 SDK 仅定义,实际需要 App 侧来实现。

插件插件名称插件名称常量
图片插件ImagePluginImagePluginName = "RC:ImagePlugin"
小视频插件CameraPluginCameraPluginName = "RC:CameraPlugin"
文件插件FilePluginFilePluginName = "RC:FilePlugin"
阅后即焚插件DestructPluginDestructPluginName = "RC:DestructPlugin"
位置插件LocationPluginLocationPluginName = "RC:LocationPlugin"

实现自定义插件

示例代码

TypeScript
import { IBoardPlugin } from '@rongcloud/imkit';
import { ConversationIdentifier } from '@rongcloud/imlib';
import { promptAction } from '@kit.ArkUI';

/**
* 自定义插件
*/
export class CustomInfoMessagePlugin implements IBoardPlugin {

/**
* 插件名,用来判断插件唯一标识
*/
pluginName(): string {
return "CustomInfoMessagePlugin"
}

/**
* 返回插件的标题
*/
obtainTitle(context: Context): string | Resource {
return "自定义小灰条消息"
}

/**
* 返回插件的图标
*/
obtainImage(context: Context): Resource {
return $r("app.media.startIcon");
}

/**
* 插件的点击事件
*/
onClick(context: Context, conId: ConversationIdentifier): void {
if (!conId) {
return;
}

// 处理具体的点击事件
// 开发者按照实际情况处理
promptAction.showToast({ message: '点击了自定义插件' })
}

/**
* 是否在会话中显示该插件
*/
onFilter(conId: ConversationIdentifier): boolean {
return true;
}
}

自定义插件UI

从 1.5.1 版本开始,IMKit 默认允许配置插件的UI组件。可以根据插件名替换自定义插件的UI,如果想替换SDK内置的插件UI,插件名参照内置插件说明

TypeScript
@Builder
export function buildCustomMessagePluginView(context: Context, convId: ConversationIdentifier) {
CustomMessagePluginView({ context: context, convId: convId })
}

@Component
export struct CustomMessagePluginView {
@Prop context: Context;
@Prop convId: ConversationIdentifier;

build() {
Column() {
Text("自定义插件名").width("100%").fontSize(12).textAlign(TextAlign.Center)
Image($r("app.media.rc_file_apk_icon")).width(40).height(40)
}.width("100%").height("100%")
.justifyContent(FlexAlign.SpaceEvenly).alignItems(HorizontalAlign.Center)
}
}

// 替换自定义插件的UI组件
RongIM.getInstance().conversationService().setBoardPluginView("CustomInfoMessagePlugin", wrapBuilder(buildCustomMessagePluginView))

将插件放到扩展栏里面

需要在聊天页面出现前调用

添加插件

TypeScript
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().addBoardPlugin(customInfoMessagePlugin);

将插件放到指定位置

提示

1.4.3 版本起,如果想调整 SDK 默认展示的插件以及插件的顺序,需要通过 动态配置扩展面板插件 功能配置。

TypeScript
let index : number = 0
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().insertBoardPlugin(index, customInfoMessagePlugin);

替换指定位置的插件,如果没有对应的索引,会将插件放到最后

提示

1.4.3 版本起,如果想调整 SDK 默认展示的插件以及插件的顺序,需要通过动态配置扩展面板插件 功能配置。

TypeScript
let index : number = 0
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().replaceBoardPlugin(index, customInfoMessagePlugin);

移除特定的插件

提示

1.4.3 版本起,如果想调整 SDK 默认展示的插件以及插件的顺序,需要通过 动态配置扩展面板插件 功能配置

TypeScript
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().removeBoardPlugin(customInfoMessagePlugin);

根据插件名移除特定的插件

  1. 自定义插件实现 pluginName() 接口返回插件名,便可以通过 removeBoardPluginByName 来移除插件。
  2. 系统插件均实现了 pluginName(),可以参照上面表格中插件对应的名字,通过 removeBoardPluginByName 来移除插件。
TypeScript
RongIM.getInstance().conversationService().removeBoardPluginByName("插件名");

清空当前的插件。

提示

该接口只能清空通过 addBoardPlugininsertBoardPluginreplaceBoardPlugin 添加的插件。通过动态配置扩展面板插件可以做到彻底清空。

TypeScript
RongIM.getInstance().conversationService().clearBoardPlugin();

动态配置扩展面板插件

如果应用程序需要动态添加、删除扩展面板插件,或者调整插件位置,建议通过创建自定义的扩展面板配置实现这些自定义需求。

您需要实现 IExtensionConfig,创建自定义的扩展面板配置类,重写 getPluginModules() 方法。您可以增加或删除扩展项,也可以调整各插件的位置。 在 SDK 初始化之后,调用 setExtensionConfig 方法设置好自定义的输入配置,SDK 会根据此配置展示扩展面板。

示例代码

TypeScript
// 获取当前的插件配置
let config = RongIM.getInstance().conversationService().getExtensionConfig()

let mCustomExtensionConfig: IExtensionConfig = {
getPluginModules: (convId: ConversationIdentifier) => {
// 根据插件配置获取对应会话标识的插件
let currentPlugins = config.getPluginModules(ConversationIdentifier.createWith2(ConversationType.Private, "TargetID"))
let plugins: ArrayList<IBoardPlugin> = new ArrayList<IBoardPlugin>()
// 这里示范了去除文件插件的操作。当然也可以根据 pluginName 来重新排序插件等操作。
for (let plugin of currentPlugins) {
if (plugin.pluginName && plugin.pluginName() !== FilePluginName) {
plugins.add(plugin)
}
}
// 添加业务侧自定义的插件
plugins.add(new TestPlugin1())
plugins.add(new TestPlugin2())
return plugins
}
}

/// 在 SDK 初始化之后调用
RongIM.getInstance().conversationService().setExtensionConfig(mCustomExtensionConfig)

文本输入框配置

IMKit 从 25.12.0 版本开始支持通过 setInputTextAreaConfig 方法传入对应的 config 对象修改文本输入框的配置。

接口定义

TypeScript
/**
* 设置输入框配置
* @param config 输入框配置
* @since 25.12.0
*/
ConversationService.setInputTextAreaConfig(config: IInputTextAreaConfig): void

参数说明

IInputTextAreaConfig

参数名类型必填说明支持版本
onTextAreaKeyEvent(event: KeyEvent, viewModel: IInputAreaViewModel) => boolean输入框键盘按键事件回调。在按下任意键时触发,返回 true 表示处理该事件,返回 false 则继续默认行为。25.12.0
onTextAreaSubmit(event: EnterKeyType, viewModel: IInputAreaViewModel) => boolean输入框 submit 事件回调。在提交(如点击发送或输入回车)时触发,返回 true 表示处理该事件,返回 false 则继续默认行为。25.12.0
enterKeyTypeEnterKeyType.NEW_LINE | EnterKeyType.Send输入框回车键类型,NEW_LINE 表示换行,Send 表示发送。 默认为 NEW_LINE25.12.0

IInputAreaViewModel

参数名类型说明支持版本
onChangeInputTextAreaContent(text: string) => void更新输入框的文本组件的内容1.7.0
getInputTextAreaContent() => string获取输入框当前的文本输入组件的内容1.7.0
sendMessage() => void发送输入框内的消息25.12.0
insertChar(char: string) => void在光标位置插入字符25.12.0

使用示例

修改 PC 端文本输入框快捷键

TypeScript
// 在 PC 端,设置 Enter 键为发送消息,Shift + Enter 为换行
let inputTextAreaConfig: IInputTextAreaConfig = {
onTextAreaKeyEvent: (event: KeyEvent, inputAreaViewModel?: IInputAreaViewModel) => {
if (event.keyCode === KeyCode.KEYCODE_SHIFT_LEFT || event.keyCode === KeyCode.KEYCODE_SHIFT_RIGHT) {
this.isShiftPressed = event.type === KeyType.Down;
}
// 设置 enterKeyType 为 send 后,未按下shift时,按enter不会触发该事件,会触发 onSubmit 事件
if ((event.keyCode === KeyCode.KEYCODE_ENTER || event.keyCode === KeyCode.KEYCODE_NUMPAD_ENTER) && event.type === KeyType.Up) {
if (this.isShiftPressed) {
inputAreaViewModel?.insertChar('\n')
}
return true
}
return false
},
enterKeyType: EnterKeyType.Send
}
RongIM.getInstance().conversationService().setInputTextAreaConfig(inputTextAreaConfig)