会话列表自定义
会话列表控制需要展示的会话类型
SDK 会话列表默认仅支持单聊和群聊两种会话。
您可以通过 setSupportedTypes 方法配置会话列表展示的会话类型。需要在会话列表展示前设置,最多可以支持单聊、群聊、系统会话。
接口定义
/**
 * 设置支持的会话类型
 * @param types 会话类型数组
 */
setSupportedTypes(types: ConversationType[]): void
参数说明
| 参数名 | 类型 | 必填 | 说明 | 
|---|---|---|---|
types | ConversationType[] | 是 | 会话类型数组,可选值:ConversationType.Private(单聊)、ConversationType.Group(群聊)、ConversationType.System(系统会话) | 
示例代码
// 读取会话列表当前的配置
let config = RongIM.getInstance().conversationListService().getConversationListConfig()
// 设置会话列表仅展示单聊
config.setSupportedTypes([ConversationType.Private])
// 更新会话列表配置
RongIM.getInstance().conversationListService().setConversationListConfig(config)
会话列表组件自定义聚合展示
您可以通过为 ConversationListComponent 组件设置 dataProcessor 参数,实现更灵活的会话列表数据源管理。
- 从 
1.7.2版本开始支持。 - 一旦使用该参数,将会覆盖前述通过 
setSupportedTypes配置的会话类型展示方式。 
接口定义
/**
 * 会话列表数据处理器接口
 */
export interface DataProcessor {
  /**
   * 支持的会话类型
   */
  supportedTypes?: ConversationType[];
  
  /**
   * 自定义获取会话列表的方法
   */
  onFetchConversationList?: (time: number) => Promise<List<Conversation>>;
  
  /**
   * 会话数据过滤方法
   */
  onConversationFilter?: (item: Conversation) => boolean;
}
参数说明
DataProcessor
| 参数名 | 类型 | 必填 | 说明 | 
|---|---|---|---|
supportedTypes | ConversationType[] | 否 | 支持的会话类型数组,用于筛选展示的会话类型 | 
onFetchConversationList | (time: number) => Promise<List<Conversation>> | 否 | 自定义获取会话列表的方法,参数 time 为时间戳,用于分页加载 | 
onConversationFilter | (item: Conversation) => boolean | 否 | 会话过滤方法,返回 true 表示显示该会话,返回 false 表示过滤该会话 | 
使用示例
示例 1:按会话类型筛选
// 仅展示单聊会话
ConversationListComponent({dataProcessor: {
  supportedTypes: [ConversationType.Private]
}})
// 仅展示群聊会话
ConversationListComponent({dataProcessor: {
  supportedTypes: [ConversationType.Group]
}})
示例 2:自定义聚合逻辑
以获取未读数不为 0 的会话列表为例:
ConversationListComponent({dataProcessor: {
  onFetchConversationList: async (time: number) => {
    // 自定义请求会话列表数据
    const cons = new List<ConversationType>()
    cons.add(ConversationType.Group)
    cons.add(ConversationType.Private)
    const list: List<Conversation> = new List<Conversation>()
    const res = await IMEngine.getInstance().getUnreadConversations(cons)
    if (res.code === EngineError.Success && res.data && res.data.length > 0) {
      res.data.forEach(item => {
        list.add(item)
      })
      options.time = res.data.getLast().lastOperateTime
    }
    return list
  },
  // 设置会话数据过滤方法
  onConversationFilter: (item: Conversation) => {
    return item.unreadMessageCount > 0
  }
}})
会话列表增加长按事件
您可以通过 addConversationItemLongClickAction 方法为会话列表添加自定义长按事件。
接口定义
/**
 * 长按事件配置接口
 */
export interface ItemLongClickAction<Conversation> {
  /**
   * 获取长按菜单显示的标题
   */
  obtainTitle: (context: Context, data: Conversation) => string | Resource;
  
  /**
   * 长按菜单项的点击事件
   */
  onClick: (context: Context, data: Conversation) => void;
  
  /**
   * 过滤条件,用于控制该长按菜单项是否显示
   */
  onFilter: (data: Conversation) => boolean;
  
  /**
   * 动作 ID,用于唯一标识该长按事件
   */
  actionId: string;
}
参数说明
ItemLongClickAction
| 参数名 | 类型 | 必填 | 说明 | 
|---|---|---|---|
obtainTitle | (context: Context, data: Conversation) => string | Resource | 是 | 长按菜单显示的标题,返回字符串或资源 ID | 
onClick | (context: Context, data: Conversation) => void | 是 | 用户点击长按菜单项时触发的回调函数 | 
onFilter | (data: Conversation) => boolean | 是 | 过滤条  件函数,返回 true 表示显示该菜单项,返回 false 表示不显示 | 
actionId | string | 是 | 动作的唯一标识符,用于区分不同的长按事件 | 
示例代码
private addConversationListLongClickAction() {
  let action: ItemLongClickAction<Conversation> = {
    // 显示标题
    obtainTitle: (context: Context, data: Conversation): string | Resource => {
      return "自定义长按事件";
    },
    // 长按 item 的点击事件
    onClick: (context: Context, data: Conversation) => {
      promptAction.showToast({ message: "会话列表自定义长按事件" })
    },
    // 过滤条件,true 代表需要显示,false 代表不会显示
    onFilter: (data: Conversation): boolean => {
      // 可以动态配置特定的 Conversation 才显示该长按 item
      return true;
    },
    actionId: 'Conversation_Custom' // 动作 Id,可自定义
  }
  RongIM.getInstance().conversationListService().addConversationItemLongClickAction(action);
}
会话列表头像圆角控制
您可以通过 setConversationAvatarStyle 方法修改会话列表头像样式。会话列表头像默认为矩形,可以修改为圆形。不支持动态切换矩形和圆形,必须在会话列表展示前设置。
接口定义
/**
 * 设置会话列表头像样式
 * @param style 头像样式
 */
setConversationAvatarStyle(style: AvatarStyle): void
参数说明
| 参数名 | 类型 | 必填 | 说明 | 
|---|---|---|---|
style | AvatarStyle | 是 | 头像样式,可选值:AvatarStyle.Cycle(圆形)、AvatarStyle.Rectangle(矩形,默认值) | 
示例代码
// 读取会话列表当前的配置
let config = RongIM.getInstance().conversationListService().getConversationListConfig()
// 设置会话列表头像为圆形
config.setConversationAvatarStyle(AvatarStyle.Cycle)
// 更新会话列表配置
RongIM.getInstance().conversationListService().setConversationListConfig(config)
会话列表点击事件
当您使用 ConversationListComponent 创建会话列表页面时,可以传入 onConversationItemClick 来处理点击事件。SDK 默认未处理点击事件,如未设置 onConversationItemClick 则表现为点击无反应。
从 1.4.3 版本开始,支持通过 addConversationListEventListener 设置会话列表点击事件,见会话列表事件。但需要注意,如果传入的 onConversationItemClick 不为空则不会再执行 ConversationListEventListener 的 onConversationClick 回调。
接口定义
/**
 * 会话列表 Item 点击事件回调
 * @param conversation 被点击的会话对象
 * @param index 会话在列表中的索引
 */
onConversationItemClick?: (conversation: Conversation, index: number) => void
参数说明
| 参数名 | 类型 | 说明 | 
|---|---|---|
conversation | Conversation | 被点击的会话对象,包含会话类型和目标 ID 等信息 | 
index | number | 会话在列表中的索引位置 | 
示例代码
@Entry
@Component
export struct ChatListPage {
  build() {
    Column() {
      ConversationListComponent({
        // 实现会话列表的点击事件
        onConversationItemClick: this.onConversationItemClick
      }).layoutWeight(1)
    }.width('100%').height('100%')
  }
  
  private onConversationItemClick(conversation: Conversation, index: number): void {
    // let params = new Conversation()
    // params.conversationType = ConversationType.Private
    // params.targetId = "会话 Id"
    // 参数必须是 Conversation 对象,必须有有效的 conversationType 和 targetId
    router.pushUrl({ url: "pages/ChatPage", params: conversation },);
  }
}
会话列表添加自定义空布局
IMKit 支持在会话列表为空时展示自定义的空白视图。您只需在构造 ConversationListComponent 时传入 emptyComponent 即可。
接口定义
/**
 * 空布局组件构建器
 * 当会话列表为空时显示的自定义组件
 */
emptyComponent?: () => void
参数说明
| 参数名 | 类型 | 必填 | 说明 | 
|---|---|---|---|
emptyComponent | () => void | 否 | 空布局组件构建器,用于构建会话列表为空时显示的自定义视图 | 
示例代码
@Entry
@Component
export struct ChatListPage {
  build() {
    Column() {
      ConversationListComponent({
        // 实现没有会话的空白页面
        emptyComponent: () => {
          this.emptyBuilder();
        }
      }).layoutWeight(1)
    }.width('100%').height('100%')
  }
  @Builder
  emptyBuilder() {
    Text(`空白页面`).width('95%').fontColor("#FF0000").padding(10)
  }
}
会话列表页面事件
IMKit 提供了会话列表事件监听器 ConversationListEventListener,可监听保存草稿、会话清除未读数、删除会话、本端或者其他端修改会话的免打扰和置顶状态、点击会话、长按会话等事件。
您需要使用 addConversationListEventListener 与 removeConversationListEventListener 方法添加或移除监听器。建议添加监听后,在合适的时机移除,避免内存泄漏。如果在页面中监听,建议在 aboutToAppear 调用,在 aboutToDisappear 移除监听。
从 1.4.3 版本开始,增加 onConversationLongClick、onConversationClick 方法。
接口定义
export interface ConversationListEventListener {
  /**
   * 当某个会话内产生保存草稿的行为时
   */
  onSaveDraft?: (identifier: ConversationIdentifier, content: string) => void;
  /**
   * 当某个会话清除未读数时
   */
  onClearedUnreadStatus?: (identifier: ConversationIdentifier) => void;
  /**
   * 当批量删除某些会话时
   */
  onRemoveConversation?: (identifierList: List<ConversationIdentifier>) => void;
  /**
   * 当其他端修改会话的免打扰和置顶状态时
   */
  onSyncConversationStatus?: (items: List<ConversationStatusInfo>) => void;
  /**
   * 当本端修改会话的置顶状态时
   */
  onConversationTopStatusChange?: (identifierList: List<ConversationIdentifier>, option: ISetConversationTopOption) => void;
  /**
   * 当本端修改会话的免打扰状态时
   */
  onConversationNotificationLevelChange?: (identifierList: List<ConversationIdentifier>, level: PushNotificationLevel) => void;
  
  /**
   * 长按会话列表中的 item 时执行
   * @param uiConversation 长按时的会话条目
   * @returns 是否处理该事件。返回 true 代表 App 处理该点击事件,SDK 不再处理;返回 false 代表由 SDK 处理点击事件
   * @version 1.4.3
   */
  onConversationLongClick?: (uiConversation: BaseUiConversation) => boolean;
  
  /**
   * 点击会话列表中的 item 时执行
   * @param uiConversation 会话条目
   * @returns 是否处理该事件。返回 true 代表 App 处理该点击事件,SDK 不再处理;返回 false 代表由 SDK 处理点击事件
   * @version 1.4.3
   */
  onConversationClick?: (uiConversation: BaseUiConversation) => boolean;
}
方法说明
ConversationListEventListener
| 方法名 | 参数 | 返回值 | 说明 | 支持版本 | 
|---|---|---|---|---|
onSaveDraft | identifier: ConversationIdentifiercontent: string | void | 当某个会话内产生保存草稿的行为时触发 | - | 
onClearedUnreadStatus | identifier: ConversationIdentifier | void | 当某个会话清除未读数时触发 | - | 
onRemoveConversation | identifierList: List<ConversationIdentifier> | void | 当批量删除某些会话时触发 | - | 
onSyncConversationStatus | items: List<ConversationStatusInfo> | void | 当其他端修改会话的免打扰和置顶状态时触发 | - | 
onConversationTopStatusChange | identifierList: List<ConversationIdentifier>option: ISetConversationTopOption | void | 当本端修改会话的置顶状态时触发 | - | 
onConversationNotificationLevelChange | identifierList: List<ConversationIdentifier>level: PushNotificationLevel | void | 当本端修改会话的免打扰状态时触发 | - | 
onConversationLongClick | uiConversation: BaseUiConversation | boolean | 长按会话列表 Item 时触发。返回 true 表示 App 处理该事件,SDK 不再处理;返回 false 表示由 SDK 处理。如果存在多个监听器,只要有 1 个监听器实现了该方法且返回 true,SDK 则不再处理该事件 | 1.4.3 | 
onConversationClick | uiConversation: BaseUiConversation | boolean | 点击会话列表 Item 时触发。优先执行 ConversationListComponent 传入的 onConversationItemClick,如果没传则执行此方法。返回 true 表示 App 处理该事件,SDK 不再处理;返回 false 表示由 SDK 处理。如果存在多个监听器,只要有 1 个监听器实现了该方法且返回 true,SDK 则不再处理该事件 | 1.4.3 | 
示例代码
let service = RongIM.getInstance().conversationListService();
// 设置监听
service.addConversationListEventListener(conversationListEventListener)
// 移除监听
service.removeConversationListEventListener(conversationListEventListener)
自定义会话列表 Item 子组件
您可以通过调用 setConversationItemComponentConfig 方法,为会话列表的每个 Item 组件添加自定义子组件。
从 1.7.2 版本开始支持。
接口定义
/**
 * 会话列表 Item 扩展组件配置
 * @since 1.8.0
 */
export interface ConversationItemComponentConfig {
  /**
   * 组件标识
   */
  identifier: ComponentIdentifier,
  /**
   * 组件 WrappedBuilder
   * @since 1.6.0
   */
  component?: WrappedBuilder<ConversationItemComponentData> | null,
}
/**
 * 会话列表 Item 扩展组件数据,封装必要的参数透传给自定义组件
 * @since 1.8.0
 */
export class ConversationItemComponentData {
  /**
   * 上下文
   */
  context: Context | undefined;
  /**
   * 会话信息
   */
  conversation: BaseUiConversation | undefined;
  /**
   * 头像配置
   * @since 1.10.0
   */
  avatarConfig?: AvatarConfig
}
参数说明
ConversationItemComponentConfig
| 参数名 | 类型 | 必填 | 说明 | 支持版本 | 
|---|---|---|---|---|
identifier | ComponentIdentifier | 是 | 组件标识,指定要自定义的组件类型。详见下方"支持的组件类型" | 1.8.0 | 
component | WrappedBuilder<ConversationItemComponentData> | 否 | 自定义组件构建器,用于构建自定义 UI 组件 | 1.6.0 | 
ConversationItemComponentData
| 参数名 | 类型 | 说明 | 支持版本 | 
|---|---|---|---|
context | Context | 应用上下文对象 | 1.8.0 | 
conversation | BaseUiConversation | 会话信息对象,包含会话的详细数据 | 1.8.0 | 
avatarConfig | AvatarConfig | 头像配置信息,包含头像尺寸等属性 | 1.10.0 | 
支持的组件类型
identifier 支持的组件类型说明:
| 组件类型 | 说明 | 支持版本 | 
|---|---|---|
ConversationItemExtensionComponent | 会话列表 Item 的扩展组件 | 1.7.2 | 
ConversationItemAvatar | 会话列表 Item 的头像组件 | 1.10.0 | 
使用示例
示例 1:为置顶会话添加自定义图标
为置顶的会话 Item 在右上角增加一个自定义图标:
@Builder
export function buildCustomConversationItemExtensionComponent(componentData: ConversationItemComponentData) {
  CustomConversationItemExtensionComponent({
    context: componentData.context,
    conversation: componentData.conversation,
  })
}
@Component
export struct CustomConversationItemExtensionComponent {
  @Prop context: Context;
  @Prop conversation: BaseUiConversation;
  build() {
    // 在会话右上角增加自定义置顶图标
    if (this.conversation.getConversation().isTop) {
      // 您需要将 “app.media.con_top” 替换为您应用中的图片资源
      Image($r('app.media.con_top')).width(12).height(12).objectFit(ImageFit.Contain)
        .alignRules({
          top: {anchor: '__container__', align: VerticalAlign.Top},
          right: {anchor: '__container__', align: HorizontalAlign.End}
        })
    }
  }
}
let ConversationItemComponent: ConversationItemComponentConfig = {
  identifier: ComponentIdentifier.ConversationItemExtensionComponent,
  component:wrapBuilder(buildCustomConversationItemExtensionComponent),
}
RongIM.getInstance().conversationListService().setConversationItemComponentConfig(ConversationItemComponent)
示例 2:自定义会话头像组件
在默认头像基础上添加自定义装饰层:
@Builder
function buildCustomConversationAvatar(data: ConversationItemComponentData) {
  // 默认头像 + 自定义装饰层
  Stack({ alignContent: Alignment.Center }) {
    RongIM.getInstance().uiComponents().getDefaultConversationAvatar().builder(data)
    Image($r('app.media.avatar_frame_sample'))
      .width(data.avatarConfig?.size)
      .height(data.avatarConfig?.size)
      .objectFit(ImageFit.Contain)
      .hitTestBehavior(HitTestMode.Transparent)
  }
}
let ConversationItemComponent: ConversationItemComponentConfig = {
  identifier: ComponentIdentifier.ConversationItemAvatar,
  component: wrapBuilder(buildCustomConversationAvatar),
}
RongIM.getInstance().conversationListService().setConversationItemComponentConfig(ConversationItemComponent)
自定义会话列表的 dataSource
通过继承 ConversationListDataSource 可以自定义会话列表的数据源,实现对数据源的增、删、改操作。
从 1.10.0 版本开始支持。
接口定义
/**
 * 会话列表数据源基类
 */
export class ConversationListDataSource {
  /**
   * 替换数据源中的数据
   * @param values 新的会话列表数据
   */
  public replaceData(values: ArrayList<BaseUiConversation>): void
}