接入融云IM-按条件弄出来两个消息列表

这需求挺常见也挺变态的,往往产品就想这些把用户区分开来,但偏偏融云默认是不支持的。

头疼一:消息它满足什么条件时,在这个列表,不满足时在另外一个列表。总之它们不能同时存在这两个列表

头疼二:往往单独列表还有各自总的未读数,它们的未读数是列表上消息的未读数的总和

这篇文章先说怎样按条件弄出两个消息列表

我接入的融云版本是:5.1.3.10

假设一个为普通的消息列表,一个是亲密度超过多少的消息列表

融云5.0版本开始有个消息列表过滤器

一、消息列表生成时的思路

由于融云的消息列表过滤器是没法和ConversationListFragment进行绑定的,但在ConversationListFragment创建是会找当前融云配置的过滤器,即虽然我们建了两个过滤器类,因为没法绑定,所以在创建什么ConversationListFragment先设置什么过滤器,这样它就根据当前的过滤器进行过滤。已经生成的ConversationListFragment的不会受到新的过滤器影响。
不知道你听懂了没有,来看参考的代码

普通的消息列表过滤器:MyDataProcessor

/**
 * @author :congge
 * @date : 2022-12-12 14:21
 * @desc :消息列表过滤器
 **/
class MyDataProcessor( val removeTargetIds :MutableSet<String>) : BaseDataProcessor<Conversation>() {

private val supportedTypes = arrayOf(
    Conversation.ConversationType.PRIVATE,
     Conversation.ConversationType.SYSTEM
)


override fun supportedTypes(): Array<Conversation.ConversationType> {
    return supportedTypes
}

override fun filtered(p0: MutableList<Conversation>): MutableList<Conversation> {
    LogUtils.i("filtered","MyDataProcessor")

    for (index in p0.count()-1 downTo 0){
        
        if (p0[index].targetId == ImType.SYS_INTERACT_NOTIFY || p0[index].targetId == ImType.SYS_ONLINE_NOTIFY
            || (MyApplication.getSysParamGlobalBean()?.customerServiceAccount == p0[index].targetId)){
            p0.removeAt(index)
        } else {
            for (removeTargetId in removeTargetIds){
                if (p0[index].targetId == removeTargetId){
                    //LogUtils.o("filtered11","移除\t"+ p0[index].targetId+"\t"+ RongUserInfoManager.getInstance().getUserInfo(p0[index].targetId).name)
                    p0.removeAt(index)
                    break
                }
            }
        }

    }




    return p0
}

override fun isGathered(p0: Conversation.ConversationType?): Boolean {
    return false
}
}

removeTargetIds就是要移除的用户,就是不在此列表显示的消息。看着是MutableSet<String>声明的,防止多次添加了。
你们只需看for (removeTargetId in removeTargetIds)即可

亲密度消息列表过滤器:MyIntimacyDataProcessor

/**
 * @author :congge
 * @date : 2022-12-12 14:21
 * @desc :亲密度消息列表过滤器
 **/
class MyIntimacyDataProcessor( val removeTargetIds :MutableSet<String>) : BaseDataProcessor<Conversation>() {

private val supportedTypes = arrayOf(
    Conversation.ConversationType.PRIVATE,
     Conversation.ConversationType.SYSTEM
)


override fun supportedTypes(): Array<Conversation.ConversationType> {
    return supportedTypes
}

override fun filtered(p0: MutableList<Conversation>): MutableList<Conversation> {
    
    
    for (index in p0.count()-1 downTo 0){
        

        if (p0[index].targetId == ImType.SYS_INTERACT_NOTIFY || p0[index].targetId == ImType.SYSTEM_LITTLE_ASSISTANT
            || (MyApplication.getSysParamGlobalBean()?.customerServiceAccount == p0[index].targetId)){
            p0.removeAt(index)
        } else {
            for (removeTargetId in removeTargetIds){
                if (p0[index].targetId == removeTargetId){
                    //LogUtils.o("filtered11","移除\t"+ p0[index].targetId+"\t"+ RongUserInfoManager.getInstance().getUserInfo(p0[index].targetId).name)
                    p0.removeAt(index)
                    break
                }
            }
        }



    }
    return p0
}

override fun isGathered(p0: Conversation.ConversationType?): Boolean {
    return false
}
}

下面开始显示列表的代码

private fun toShowImListView(targetIds:MutableSet<String>){
    if (msgListType == MsgOutFragment.intimacyMsgListType){
        myIntimacyDataProcessor = MyIntimacyDataProcessor(targetIds)
        RongConfigCenter.conversationListConfig().setDataProcessor(
            myIntimacyDataProcessor
        )
    } else {
        myDataProcessor = MyDataProcessor(targetIds)
        RongConfigCenter.conversationListConfig().setDataProcessor(myDataProcessor)
    }
    if (isMBindingViewInitialised()){
        mListFragment = ConversationListFragmentEx()
        val transaction = childFragmentManager.beginTransaction()
        transaction.replace(R.id.fl_msg_content,mListFragment!!)
        transaction.commit()
    } else {
        showRealView()
    }

}

参数targetIds:MutableSet<String>就是你请求接口,需要移除的用户。你看我在创建ConversationListFragmentEx时都设置了当前的过滤是什么。
这里我请求接口代码没放出来,思路是通过RongIM.getInstance().getConversationList获取所有会话集合传给接口,接口来判断这个消息该在那个列表。不用生成ConversationListFragment,getConversationList里面也是有数据的

二、处理单个的会话的归属列表

如果一开始没有这个会话的,它来了怎么办呢,如果你处理,它会同时存在两个消息列表中。产品和测试肯定找你,他们最喜欢找这种问题了。

这处理起来就麻烦了,问融云技术也没解决,他们说没遇到过这么复杂的需求。

如果你们允许来一条消息就重新请求上面刚加载消息列表的接口,消息列表重新加载的。就重新用消息列表处理即可。

我项目还有单个用户的接口判断它在那个列表的。我们接着讲

思路:一开始它来消息了会存在两个列表中,存在一下没关系,这时请求单个用户的接口,接口判断它在那个列表,我们要手动移除它,并添加到对应的过滤器中,并且设置当前消息列表的过滤器。

参考代码如下:

先定义个通知bean

data class MsgListRemoveTargetIdEvent(
    val msgListType:Int,
    val targetId:String,
    val isRemoveOrAdd:Int, //0是添加移除,1是移除集合中移除
)

在onReceived()消息监听中请求单个接口,请求完发通知到消息列表

if (it.chatIntimacy?.messageListState == 1){
                    EventBus.getDefault().post(MsgListRemoveTargetIdEvent(MsgOutFragment.normalMsgListType,msg.targetId,0))
                    EventBus.getDefault().post(MsgListRemoveTargetIdEvent(MsgOutFragment.intimacyMsgListType,msg.targetId,1))
                } else {
                    EventBus.getDefault().post(MsgListRemoveTargetIdEvent(MsgOutFragment.intimacyMsgListType,msg.targetId,0))
                    EventBus.getDefault().post(MsgListRemoveTargetIdEvent(MsgOutFragment.normalMsgListType,msg.targetId,1))
                }  

我的等于1在亲密度消息列表

@Subscribe(threadMode = ThreadMode.MAIN)
fun onMsgListRemoveTargetIdEvent(eventData: MsgListRemoveTargetIdEvent) {
    if (eventData.msgListType == MsgOutFragment.intimacyMsgListType) {
        myIntimacyDataProcessor?.let {
            if (eventData.isRemoveOrAdd == 0){
                it.removeTargetIds.add(eventData.targetId)
                mListFragment?.wrappedAdapter?.data?.let { listData ->
                    for (index in listData.count()-1 downTo 0){
                        if (listData[index].mCore.targetId == eventData.targetId){
                            mListFragment?.wrappedAdapter?.data?.removeAt(index)
                            mListFragment?.wrappedAdapter?.notifyDataSetChanged()
                            break
                        }
                    }
                }
                LogUtils.i("onMsgListRemoveTargetIdEvent","1")
            } else {
                it.removeTargetIds.remove(eventData.targetId)
                LogUtils.i("onMsgListRemoveTargetIdEvent","2")
            }

            mListFragment?.mConversationListViewModel?.setmDataFilter(it)
            mListFragment?.mConversationListViewModel?.getConversation(Conversation.ConversationType.PRIVATE,eventData.targetId)
        }

    }} 

以上就是根据条件弄出两个消息列表来。关键代码都在了。有问题可以先问融云技术,再不行可私信我,我们来讨论下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章