SortedList继承于java.lang.Object
,是android.support.v7.util
包下的工具类。这个类,与java.util包下的ArrayList、List等类没有丝毫的关系,不管是继承还是实现。而,又与它们相像,在这个类的内部,封装了对一系列对数据的操作:插入,删除,移动,更新等。
SortedList实际上是一个排序列表的实现,提供处理了两种角色:
也就是说,SortedList里面的数据集是按照指定的条件排序的,不需要再为排序而烦恼。而,和ArrayList、List等类的排序方式是一样的,它通过compare(Object,Object)方法对Item进行排序,这样又显得不陌生。对于Item的搜索,它采用的二进制搜索来检索Item,提高了检索的效率。
SortedListAdapterCallback:它是SortedListAdapterCallback的实现类,主要与RecyclerView.Apdater配合使用,在它内部定义了RecyclerView.Apdater,同时实现了数据集变化时的更新操作。此时,只需要实现以下3个方法即可:
这里需要注意的是,BatchedCallback和SortedListAdapterCallback是不同的,尽管它们都是SortedList.Callback的实现类:
SortedList基于维持列表中Item的顺序这一特性,在实际开发过程中,还是带来很多的遍历。比如,在查看成绩列表时,只需将成绩添加至列表即可,它会自动排序,我们不需要再考虑。下面就是SortedList的示例。
创建bean类
data class StudentBean(val no: Int, val name: String, val rank: Int)
创建SortedListAdapterCallback的实现类
class StudentCallback>(@NonNull private val adapter: T) : SortedListAdapterCallback(adapter) {
// 默认按照学号排序
private var sortedType = SortedListActivity.SortedType.RANK
// 判断两个Item是否相同
override fun areItemsTheSame(item1: StudentBean?, item2: StudentBean?): Boolean {
return item1?.no == item2?.no
}
// 排序条件
override fun compare(o1: StudentBean?, o2: StudentBean?): Int {
return when (sortedType) {
SortedListActivity.SortedType.NO -> o1!!.no - o2!!.no
SortedListActivity.SortedType.NO_REVERSE -> o2!!.no - o1!!.no
SortedListActivity.SortedType.RANK -> o1!!.rank - o2!!.rank
SortedListActivity.SortedType.RANK_REVERSE -> o2!!.rank - o1!!.rank
}
}
// 判断两个Item的内容是否相同
override fun areContentsTheSame(oldItem: StudentBean?, newItem: StudentBean?): Boolean {
return oldItem == newItem
}
// 设置排序类型
fun setType(type: SortedListActivity.SortedType) {
this.sortedType = type
}
}
在StudentCallback这个实现类中,指定了按学号正序/逆序或者排名正序/逆序这这四种方式进行排序。
创建Adapter
class StudentAdapter : RecyclerView.Adapter() {
val mCallback = StudentCallback(this)
val mSortedList = SortedList(StudentBean::class.java, SortedList.BatchedCallback(mCallback))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StudentViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_student, parent, false)
return StudentViewHolder(view)
}
override fun getItemCount(): Int {
return mSortedList.size()
}
override fun onBindViewHolder(holder: StudentViewHolder, position: Int) {
val bean = mSortedList.get(position)
holder.tvNoValue.text = bean.no.toString()
holder.tvNameValue.text = bean.name
holder.tvRankValue.text = bean.rank.toString()
}
}
更新数据集
private fun resetData() {
with(mAdapter.mSortedList) {
beginBatchedUpdates()
clear()
// 当SortedList清空数据时,Adapter必须调用notifyDataSetChanged
// 否则报异常 java.lang.IndexOutOfBoundsException: Inconsistency detected.
mAdapter.notifyDataSetChanged()
addAll(mList)
endBatchedUpdates()
}
}
DiffUtilDemo