изменение значения списка внутри viewmodel наблюдать заставляет список действовать не так, как задумано - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть следующая функция -

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, и это тоже не помогло, так что я действительно ничего не понимаю. .

Кажется, что-то очень маленькое, что мне здесь не хватает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...