You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:17:58