这需求挺常见也挺变态的,往往产品就想这些把用户区分开来,但偏偏融云默认是不支持的。
头疼一:消息它满足什么条件时,在这个列表,不满足时在另外一个列表。总之它们不能同时存在这两个列表
头疼二:往往单独列表还有各自总的未读数,它们的未读数是列表上消息的未读数的总和
这篇文章先说怎样按条件弄出两个消息列表
我接入的融云版本是: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)
}
}}
以上就是根据条件弄出两个消息列表来。关键代码都在了。有问题可以先问融云技术,再不行可私信我,我们来讨论下。
网友评论