這需求挺常見也挺變態的,往往產品就想這些把用戶區分開來,但偏偏融雲默認是不支持的。
頭疼一:消息它滿足什麼條件時,在這個列表,不滿足時在另外一個列表。總之它們不能同時存在這兩個列表
頭疼二:往往單獨列表還有各自總的未讀數,它們的未讀數是列表上消息的未讀數的總和
這篇文章先說怎樣按條件弄出兩個消息列表
我接入的融雲版本是: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)
}
}}
以上就是根據條件弄出兩個消息列表來。關鍵代碼都在了。有問題可以先問融雲技術,再不行可私信我,我們來討論下。