RecycleView 列表動(dòng)態(tài)刷新鲤竹,頁(yè)面不動(dòng),只刷新某個(gè)符合條件的item
有人用過 DiffUtil 比吭,也可以刺覆,不過發(fā)現(xiàn)了SortedList 更好严肪。寫了一個(gè)測(cè)試
- SortedList是一個(gè)有序列表(數(shù)據(jù)集)的實(shí)現(xiàn),可以保持ItemData都是有序的谦屑,并(自動(dòng))通知列表(RecyclerView)(數(shù)據(jù)集)中的更改驳糯。
data class TestListBean(
var index:Int,
var tag:String,
)
自定義一個(gè)SortedList
class SortListCallBack(adapter: TestSortedAdapter?):SortedListAdapterCallback<TestListBean>(adapter) {
override fun compare(o1: TestListBean?, o2: TestListBean?): Int {
o1 ?: return -1
o2 ?: return -2
return o1.index - o2.index
}
override fun areContentsTheSame(oldItem: TestListBean?, newItem: TestListBean?): Boolean {
if (oldItem?.index != newItem?.index){
return false
}
if (oldItem?.tag != newItem?.tag){
return false
}
return true
}
override fun areItemsTheSame(item1: TestListBean?, item2: TestListBean?): Boolean {
return item1?.index == item2?.index
}
override fun getChangePayload(item1: TestListBean?, item2: TestListBean?): Any? {
return super.getChangePayload(item1, item2)
}
}
適配器
class TestSortedAdapter:BaseQuickAdapter<TestListBean,BaseViewHolder>(R.layout.item_test_sort_layout) {
val mCallback =SortListCallBack(this)
val mSortedList = SortedList(TestListBean::class.java,SortedList.BatchedCallback(mCallback))
override fun onItemViewHolderCreated(viewHolder: BaseViewHolder, viewType: Int) {
super.onItemViewHolderCreated(viewHolder, viewType)
ItemTestSortLayoutBinding.bind(viewHolder.itemView)
}
override fun convert(holder: BaseViewHolder, item: TestListBean) {
holder.getBinding<ItemTestSortLayoutBinding>()?.run {
tvTagName.text = item.tag
}
}
fun setSortedList(list: MutableList<TestListBean>){
data.addAll(list)
mSortedList.addAll(list)
}
fun sorted():SortedList<TestListBean>{
return mSortedList
}
}
Activity
class MainActivity : AppCompatActivity() {
private lateinit var binding:ActivityMainBinding
private val viewModel by viewModels<ListViewModel>()
private var adapter:TestSortedAdapter? = null
@SuppressLint("NotifyDataSetChanged")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel.listData.observe(this){
adapter?.setSortedList(it)
}
if (adapter == null){
adapter = TestSortedAdapter()
}
binding.recycleView.adapter = adapter
viewModel.initList()
binding.btnChange.setOnClickListener {
val index = (0..20).random()
WLog.e("btnChange","=====> 更新下標(biāo):$index")
val list = mutableListOf<TestListBean>()
adapter?.data?.let { it1 -> list.addAll(it1) }
val bean = list.find { it.index == index }
bean?.tag = "更新:$index"
adapter?.sorted()?.run {
beginBatchedUpdates()
clear()
adapter?.notifyDataSetChanged()
addAll(list)
endBatchedUpdates()
}
}
}
}
ListViewModel 只是一個(gè)初始化測(cè)試數(shù)據(jù)的。
當(dāng)前幾右下按鈕時(shí)氢橙,隨時(shí)的下標(biāo)數(shù)據(jù)開始更新酝枢,頁(yè)面直接更新對(duì)應(yīng)的item 不會(huì)發(fā)生移動(dòng)
下圖,更新后的頁(yè)面:
參考:IM會(huì)話列表刷新優(yōu)化思考 https://juejin.cn/post/7183517773790707769