Android MVVM架构下RecyclerView删除无响应,Dao方法失效求助
RecyclerView点击删除无反应的问题修复
问题核心原因
你在SecondActivity里犯了一个关键错误:单独inflate了一个RecyclerView的item布局,然后给这个根本没加到RecyclerView里的孤立View设置点击事件,实际列表中的item删除按钮根本没绑定点击逻辑,所以点击自然没反应。
另外还有两个次要问题:
- LiveData观察里的循环提交列表完全多余,会导致多次重复提交
- 手动调用
adapter.notifyItemRemoved没必要,因为Room数据更新后LiveData会自动通知,submitList会通过DiffUtil自动更新UI
修复步骤
1. 修改CardListAdapter,添加删除点击回调
让Adapter负责绑定item内控件的点击事件,通过接口把点击事件传递给上层:
class CardListAdapter(private val onDeleteClick: (CardPair) -> Unit) : ListAdapter<CardPair, CardListAdapter.WordViewHolder>(WordsComparator()) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder { return WordViewHolder.create(parent) } override fun onBindViewHolder(holder: WordViewHolder, position: Int) { val current = getItem(position) holder.bind(current.front, current.back) // 给删除按钮设置点击事件 holder.itemView.findViewById<ImageView>(R.id.imageDelete).setOnClickListener { onDeleteClick(current) } } class WordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { private val wordItemView: TextView = itemView.findViewById(R.id.textView) private val deftext: TextView = itemView.findViewById(R.id.text1) fun bind(text: String?, text1: String?) { wordItemView.text = text deftext.text = text1 } companion object { fun create(parent: ViewGroup): WordViewHolder { val view: View = LayoutInflater.from(parent.context) .inflate(R.layout.recyclerview, parent, false) return WordViewHolder(view) } } } class WordsComparator : DiffUtil.ItemCallback<CardPair>() { override fun areItemsTheSame(oldItem: CardPair, newItem: CardPair): Boolean { // 用主键判断,替代原有的对象引用判断(Room查询返回新对象,引用会变化) return oldItem.front == newItem.front } override fun areContentsTheSame(oldItem: CardPair, newItem: CardPair): Boolean { return oldItem.front == newItem.front && oldItem.back == newItem.back } } }
2. 修复SecondActivity的逻辑
移除孤立的View inflate代码,正确初始化Adapter并传递删除回调,简化LiveData观察逻辑:
class SecondActivity : AppCompatActivity() { lateinit var binding: SecondBinding val cardViewmodel: CardViewmodel by viewModels { WordViewModelFactory((application as CardsApplication).repository) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = SecondBinding.inflate(layoutInflater) setContentView(binding.root) // 初始化Adapter,传入删除点击回调 val adapter = CardListAdapter { cardPair -> cardViewmodel.deleteCards(cardPair) } binding.recyclerview1.adapter = adapter binding.recyclerview1.layoutManager = LinearLayoutManager(this) // 观察LiveData,数据变化时直接提交列表 cardViewmodel.allWords.observe(this) { cardPairs -> adapter.submitList(cardPairs) } } }
3. 其他说明
CardViewmodel、Repository、Dao和Entity类的逻辑都是正确的,无需修改。修改后点击RecyclerView列表项的删除按钮,就能正确触发数据库删除操作,Room数据更新后LiveData会自动通知Adapter刷新UI。
内容的提问来源于stack exchange,提问作者PurpleRabbit
相关产品推荐
相关产品推荐

