RecyclerView删除数据调用notifyDataSetChanged后未实时刷新问题
问题根因
- 删除操作是异步数据库操作,你在Adapter删除按钮点击事件中调用
viewModel.deleteVocabulary()后立刻执行notifyDataSetChanged()时,数据库删除动作还未完成,Adapter持有的favouritesList还是未删除的旧数据,这次刷新完全是无效操作,不会带来任何视图变化。 - 你已经在Fragment中实现了正确的观察者逻辑:数据库数据变更后
favouritesListLiveData会推送最新的列表数据,触发updateList()替换Adapter数据源并刷新,但你多余的提前刷新操作没有任何实际作用。 - 切换Fragment再返回时能看到删除结果,是因为Fragment回到前台时会重新触发LiveData数据回调,此时
updateList()才拿到了数据库删除后的最新列表,完成视图刷新。 - 额外隐藏问题:你在
onBindViewHolder中直接使用传入的position参数获取列表项存在风险,RecyclerView条目复用时该参数不会实时更新,连续删除、快速滑动场景下容易取错数据、触发数组越界崩溃。
修复步骤
删除Adapter点击事件中多余的
notifyDataSetChanged()调用,刷新逻辑统一交给LiveData数据回调后的updateList()处理,不要在数据未更新时手动触发刷新。
修改后的点击逻辑代码如下:holder.binding.deleteButtonRV.setOnClickListener { // 仅触发删除操作,不要在此处手动刷新列表 viewModel.deleteVocabulary(favouritesList[holder.bindingAdapterPosition]) }注意这里把原来的
position替换为holder.bindingAdapterPosition,保证每次点击都能获取到条目的真实位置。(推荐优化)移除Adapter中对ViewModel的持有,将点击事件通过函数参数回调给Fragment处理,保持Adapter单一职责,避免ViewModel作用域异常或内存泄漏问题。
改造后的Adapter构造与核心逻辑:// 删除构造参数中的ViewModelStoreOwner,新增删除点击回调参数 class FavouritesAdapter( val favouritesList : ArrayList<Vocabulary>, private val onDelete: (Vocabulary) -> Unit ) : RecyclerView.Adapter<FavouritesAdapter.FavouritesViewHolder>() { class FavouritesViewHolder(val binding: FavouritesItemRowBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavouritesViewHolder { return FavouritesViewHolder(FavouritesItemRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } override fun onBindViewHolder(holder: FavouritesViewHolder, position: Int) { val currentItem = favouritesList[holder.bindingAdapterPosition] holder.binding.englishWordTV.text = currentItem.word holder.binding.turkishWordTV.text = currentItem.translation holder.binding.deleteButtonRV.setOnClickListener { onDelete(currentItem) } } override fun getItemCount(): Int = favouritesList.size fun updateList(myList : List<Vocabulary>) { favouritesList.clear() favouritesList.addAll(myList) notifyDataSetChanged() } }在Fragment中初始化Adapter时传入点击处理逻辑即可:
favouritesAdapter = FavouritesAdapter(arrayListOf()) { vocab -> viewModel.deleteVocabulary(vocab) }
改造完成后,点击删除按钮触发数据库异步删除,删除完成后LiveData会自动推送最新列表,updateList()会自动替换数据源并刷新视图,不需要额外手动调用刷新方法,删除结果会实时同步到RecyclerView。
内容的提问来源于stack exchange,提问作者Ugur
相关产品推荐
相关产品推荐

