У меня есть следующая функция -
private fun initRoomObserving() {
dashboardViewModel = ViewModelProvider(this).get(DashboardViewModel::class.java)
dashboardViewModel.getAllMessagesEntities(currentGroupId).observe(this, Observer { receivedMessageList ->
receivedMessageList.forEach {
it.isReceiver = it.senderUsername != userPhoneNumber
if (!messagesList.contains(it) && currentGroupId == it.groupId) {
messagesList.add(it)
lastMessage = it.content
}
}
conversationAdapter.notifyItemInserted(messagesList.size)
conversationAdapter.notifyItemRangeChanged(messagesList.size - 1, 1)
conversationRecyclerview.scrollToPosition(messagesList.size - 1)
})
}
и следующий адаптер -
class ConversationAdapter(private val messages: List<MessageModelEntity>, private val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val textView = LayoutInflater.from(context).inflate(R.layout.text_message_view_holder, parent, false)
return when (viewType) {
GroupSyncModel.MessageType.Text.value -> {
TextMessageViewHolder(textView)
}
GroupSyncModel.MessageType.Media.value -> {
val mediaView = LayoutInflater.from(context).inflate(R.layout.media_message_view_holder, parent, false)
MediaMessageViewHolder(mediaView)
}
GroupSyncModel.MessageType.Contact.value -> {
val contactView = LayoutInflater.from(context).inflate(R.layout.contact_message_view_holder, parent, false)
ContactMessageViewHolder(contactView)
}
else -> TextMessageViewHolder(textView)
}
}
override fun getItemCount(): Int = messages.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is TextMessageViewHolder) setTextMessage(position, holder)
if (holder is MediaMessageViewHolder) setMediaMessage(position, holder)
if (holder is ContactMessageViewHolder) setContactMessage(position, holder)
}
private fun setContactMessage(position: Int, holder: ContactMessageViewHolder) {
val messageModelEntity = messages[position]
val model = Gson().fromJson(messageModelEntity.content, ConversationContactModel::class.java)
ConversationUtils.setHolderAsSenderOrReceiver(holder.readIndicator, holder.rootLayout, messageModelEntity.isReceiver)
holder.contactName.text = model.name
holder.topClickableArea.setOnClickListener {
GeneralViewUtils.setFragmentTransaction(
context as FragmentActivity,
R.id.activity_conversation_root_layout, ConversationContactsInformationFragment(listOf(model))
)
}
}
private fun setMediaMessage(position: Int, holder: MediaMessageViewHolder) {
val model = messages[position]
ConversationUtils.setHolderAsSenderOrReceiver(holder.readIndicator, holder.rootLayout, model.isReceiver)
val imageUrl = Constants.twoverteBaseUrl.plus(Constants.mediaGetQueryParams).plus(model.content)
val authorization = App.context?.getSharedPreferences(Constants.authorizationPrefs, Context.MODE_PRIVATE)?.getString(Constants.authorizationToken, Constants.defaultStringValue)
val imageWithAuthorization = imageUrl.plus(App.context!!.getString(R.string.conversation_images_header)).plus(authorization)
Picasso.get().load(imageWithAuthorization).into(holder.image)
}
private fun setTextMessage(position: Int, holder: TextMessageViewHolder) {
val model = messages[position]
ConversationUtils.setHolderAsSenderOrReceiver(holder.readIndicator, holder.rootLayout, model.isReceiver)
holder.content.text = model.content
}
override fun getItemViewType(position: Int): Int {
return if (messages[position].messageType == null) {
GroupSyncModel.MessageType.Text.value
} else {
messages[position].messageType!!
}
}
}
object ConversationUtils { //(from a different file)
fun setHolderAsSenderOrReceiver(readIndicator: ImageView, rootLayout: ViewGroup, isReceiver: Boolean) {
if (isReceiver) {
readIndicator.visibility = View.GONE
rootLayout.background = App.context?.getDrawable(R.drawable.shape_chat_receiver_background)
}
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что когда новые элементы поступают в список в режиме реального времени (а не при первом рендеринге списка) и когда код достигает it.isReceiver = it.senderUsername != userPhoneNumber
, логика c работает не так, как задумано - интерфейс отправителя / получателя не работает при необходимости и переключается на (насколько я могу судить) ) случайное значение между тем, кто является держателем просмотра отправителя и держателем просмотра получателя
Почему это происходит? Я думаю, это как-то связано с перезаписью списка, но я уже пытался установить значение isReceiver
в false в начале forEach l oop, и это тоже не помогло, так что я действительно ничего не понимаю. .
Кажется, что-то очень маленькое, что мне здесь не хватает.