Dr.*_*yOk 4 android android-recyclerview android-diffutils
在我的应用程序中,我想使用RecyclerView适配器并设置我使用的数据DiffUtils。
我想从服务器搜索数据然后将其显示到RecyclerView!
我写了下面的代码,但是搜索数据后显示项目重叠!
我想先清除以前的数据,然后添加新项目!
片段代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//InitViews
binding.apply {
searchEdt.addTextChangedListener {
val search = it.toString()
if (search.isNotEmpty()) {
viewModel.searchList.observe(viewLifecycleOwner) { response ->
lastMoviesAdapter.differ.submitList(response.data)
searchMoviesRecycler.initRecycler(LinearLayoutManager(requireContext()), lastMoviesAdapter)
}
viewModel.loadSearchMovies(search)
} else {
Snackbar.make(view, getString(R.string.fillAllFields), Snackbar.LENGTH_SHORT).show()
}
}
Run Code Online (Sandbox Code Playgroud)
适配器代码:
class LastMoviesAdapter @Inject constructor() : RecyclerView.Adapter<LastMoviesAdapter.ViewHolder>() {
private lateinit var binding: ItemHomeMoviesLastBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
binding = ItemHomeMoviesLastBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder()
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(differ.currentList[position])
holder.setIsRecyclable(false)
}
override fun getItemCount() = differ.currentList.size
inner class ViewHolder : RecyclerView.ViewHolder(binding.root) {
@SuppressLint("SetTextI18n")
fun bind(item: Data) {
binding.apply {
moviePosterImg.load(item.poster) {
crossfade(true)
crossfade(1000)
}
movieNameTxt.text = item.title
movieRateTxt.text = item.imdbRating
movieCountryTxt.text = item.country
movieYearTxt.text = item.year
}
}
}
private val differCallback = object : DiffUtil.ItemCallback<Data>() {
override fun areItemsTheSame(oldItem: Data, newItem: Data): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Data, newItem: Data): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)
}
Run Code Online (Sandbox Code Playgroud)
我该如何修复它?
创建一个像这样的 diff utils(可以在适配器类中执行)
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()
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的适配器中创建两个方法
// set data
fun setData(data: List<Any>) {
this.data = data.toMutableList()
}
// add new data
fun setNewData(newData: List<Any>) {
val diffCallback = DiffUtilCallback(data, newData)
val diffResult = DiffUtil.calculateDiff(diffCallback)
data.clear()
data.addAll(newData)
diffResult.dispatchUpdatesTo(this)
}
Run Code Online (Sandbox Code Playgroud)
在片段/活动中执行此操作
adapter = AdapterDual(recycler, lifecycleScope) // init adapter
adapter.setData(list) // set data
recycler.layoutManager = LinearLayoutManager(activity)
recycler.adapter = adapter // set adapter on recycler
// and when you load new data or replace it
adapter.setNewData(newList)
Run Code Online (Sandbox Code Playgroud)
请记住,如果您正在加载更多项目,那么
newList将包含之前的项目以及已加载的项目
| 归档时间: |
|
| 查看次数: |
5129 次 |
| 最近记录: |