接入融雲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)
        }

    }} 

以上就是根據條件弄出兩個消息列表來。關鍵代碼都在了。有問題可以先問融雲技術,再不行可私信我,我們來討論下。

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