在Kotlin中按两个条件对RecyclerView排序

xuo3flqw  于 2023-08-06  发布在  Kotlin
关注(0)|答案(1)|浏览(150)

我有一个包含复选框的元素的recyclerView。目前,当复选框被选中时,它会转到最后一个位置,如果未选中,它会转到顶部位置(索引0)。因此,所有未选中的都在顶部部分,而选中的则在底部部分。但是,我希望在检查/取消检查时不要直接转到顶部或底部,而是根据数据类的两个标准(checked(boolean)和order(int))转到它的排序位置。
作为一个说明性的例子,我有10个元素。当前底部有3个checked元素(它们的order分别为1,3,5),我刚刚检查了一个新元素(其order#为2),我希望该元素进入“checked”部分并直接进入正确的插槽(1,2,3,5),其中5位于最后一个位置。取消选中一个元素也是如此。如果我取消选中order# 5的元素,它应该转到未选中元素的顶部,并直接转到未选中元素的正确顺序位置,如(4,5,6,7,8,9,10)。
在Adapter.kt中
这些是我目前使用的方法:

fun unchecked() {
                val toPosition = list.size - 1
                val item = list[holder.position]
                list.removeAt(holder.position)
                list.add(toPosition, item)
                notifyItemMoved(holder.position, toPosition)
            }

            fun checked() {
                val toPosition = 0
                val item = list[holder.position]
                list.removeAt(holder.position)
                list.add(toPosition, item)
                notifyItemMoved(holder.position, toPosition)
            }

字符串
我试着在上面的方法中实现以下内容,或者作为一个独立的方法在之后调用,但是遇到了元素重复或不反映其正确位置和其他奇怪的问题。

fun sort() {
   list.sortWith(compareBy<Model> { it.checked }.thenBy { it.order})
notifyDataSetChanged()
}


感谢您的任何建议。

9nvpjoqh

9nvpjoqh1#

您可以使用DiffUtil代替直接与RecyclerView交互来删除或排序某些项目。它已经实现了所有这些逻辑,您只需要实现一个回调,其中包含一些方法来告诉它如何检查项是否相等。这将使RecyclerView及其适配器能够在您向其传递新数据时自动检测数据集的更改。
过滤本身可以在viewModel或presenter中进行,只需要将过滤后的列表传递给UI进行显示即可。

示例

实现DiffUtil.Callback

class DiffUtilCallback(private val oldList: List<Any>, private val newList: List<Any>) :
        DiffUtil.Callback() {

        // old size
        override fun getOldListSize(): Int = oldList.size

        // new list size
        override fun getNewListSize(): Int = newList.size

        // if items are same
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldItem = oldList[oldItemPosition]
            val newItem = newList[newItemPosition]
            return oldItem.javaClass == newItem.javaClass
        }

        // check if contents are same
        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldItem = oldList[oldItemPosition]
            val newItem = newList[newItemPosition]

            return oldItem.hashCode() == newItem.hashCode()
        }
    }

字符串
并使用它将更新分发到RecyclerViewAdapter:

class YourAdapter : RecyclerView.Adapter {

   fun setNewData(newData: List<Any>) {
        val diffCallback = DiffUtilCallback(data, newData)
        val diffResult = DiffUtil.calculateDiff(diffCallback)
        data.clear()
        data.addAll(newData)
        diffResult.dispatchUpdatesTo(this)
    }

}


来源:How to use DiffUtils In RecyclerViewAdapter on Android

相关问题