id在使用DiffUtil时更改RecyclerView中奇数行

id在使用DiffUtil时更改RecyclerView中奇数行

本文介绍了android在使用DiffUtil时更改RecyclerView中奇数行的背景颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个RecyclerView,每个奇数行都有不同的背景色.我尝试添加DiffUtil来加快更新速度,如下所示:

I have a RecyclerView and Every odd row has a different background color.I try to add DiffUtil to speed up the updates like this:


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.asdf.android.R
import com.asdf.android.network.model.trade.MarketTradeItem
import kotlinx.android.synthetic.main.row_trade_history.view.*

class MarketTradesListAdapter(
    private val context: Context,
    private var list: MutableList<MarketTradeItem>,
    val theme: Int
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val inflate =
            LayoutInflater.from(parent.context).inflate(R.layout.row_trade_history, parent, false)
        return ItemHolder(inflate)
    }

    override fun getItemCount(): Int {
        return list.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val itemHolder = holder as ItemHolder
        itemHolder.bind(list[position], position)
    }

    override fun onBindViewHolder(
        holder: RecyclerView.ViewHolder,
        position: Int,
        payloads: MutableList<Any>
    ) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads)
        } else {
            val payload = payloads[0] as DiffUtilPayload
            val itemHolder = holder as ItemHolder
            itemHolder.bind(list[position], position, payload)
        }
    }

    fun setList(it: List<MarketTradeItem>) {
        it.forEachIndexed { index, item -> item.position = index }

        DiffUtil.calculateDiff(DiffCallback(list, it),true).dispatchUpdatesTo(this)

        list.clear()
        list.addAll(it)
    }

    inner class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(
            order: MarketTradeItem,
            position: Int,
            payload: DiffUtilPayload = DiffUtilPayload()
        ) {


            var color: Int
            if (theme == R.style.Apptheme) {
                color = R.color.listBackgroundColorLight
            } else {
                color = R.color.listBackgroundColorDark
            }
//            if (payload.isPositionChanged)
            itemView.setBackgroundColor(
                if (position % 2 == 0) ContextCompat.getColor(
                    itemView.context,
                    android.R.color.transparent
                ) else
                    ContextCompat.getColor(itemView.context, color)
            )


            itemView.textViewPrice.setTextColor(
                ContextCompat.getColor(
                    itemView.context,
                    if (order.isRaise) R.color.buy_green else R.color.sell_red
                )
            )
            if (payload.isPriceChanged) {
                itemView.textViewPrice.text = order.price
            }
            if (payload.isAmountChanged) {
                itemView.textViewAmount.text = order.amount
            }
            if (payload.isTimeChanged) {
                itemView.textViewTime.text = order.time
            }


        }
    }

    class DiffCallback(
        private val oldList: List<MarketTradeItem>,
        private val newList: List<MarketTradeItem>
    ) : DiffUtil.Callback() {
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition] == newList[newItemPosition]
        }

        override fun getOldListSize(): Int {
            return oldList.size
        }

        override fun getNewListSize(): Int {
            return newList.size
        }

        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition] == newList[newItemPosition]
        }

        override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
            val oldItem = oldList[oldItemPosition]
            val newItem = newList[oldItemPosition]
            return DiffUtilPayload(
                oldItem.price != newItem.price,
                oldItem.amount != newItem.amount,
                oldItem.createdAt != newItem.createdAt,
                oldItem.time != newItem.time,
                oldItem.position != newItem.position
            )
        }

    }

    data class DiffUtilPayload(
        val isPriceChanged: Boolean = true,
        val isAmountChanged: Boolean = true,
        val isCreatedAtChanged: Boolean = true,
        val isTimeChanged: Boolean = true,
        val isPositionChanged: Boolean = true
    )

}

问题在于,将新项目插入列表时,偶数行和奇数行的背景色显示不正确,并且显示如下:

The problem is that the background color of even and odd rows does not appear correctly when new items are inserted to the list and appears like this:

背景颜色是随机设置的,不会显示为交替的偶数/奇数.我该怎么做才能解决此问题?

The background color is set randomly and not appear as alternate even/odd.What can I do to fix this?

推荐答案

我认为您需要在DiffUtil中更改areContentsTheSame方法.如果内容相同,则不会计算不会向适配器分派notifyItemChanged(position)的更改.并且不会为该位置/项目调用onBindViewHolder.

I think you need to change areContentsTheSame method in your DiffUtil. If the contents are same, it won't calculate the change which won't dispatch notifyItemChanged(position) to the adapter. And it won't call onBindViewHolder for that position/item.

您应该尝试将方法更改为

You should try changing the method to

override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
    return oldList[oldItemPosition] == newList[newItemPosition] && oldItemPosition % 2 == newItemPosition % 2
}

这篇关于android在使用DiffUtil时更改RecyclerView中奇数行的背景颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 22:59