Kotlin中如何实现ArrayList所有项完成后才弹出AlertDialog
问题根因
- 你在
onBindViewHolder方法中每次绑定item项时都会执行ibadahs_isCompleted = ArrayList()清空已完成状态列表,这会导致该列表始终为空或者只包含部分数据。空列表调用contains(false)返回false,因此!ibadahs_isCompleted.contains(false)恒为true,任意勾选操作都会触发弹窗。 - 你在勾选Checkbox后没有更新本地的
ibadahs_isCompleted列表或者ibadahslist中对应项的isComplete状态,判断全选时用的始终是初始加载的旧状态,逻辑完全不符合预期。 patchIbadah是异步网络请求,你在点击Checkbox后立刻判断全选状态,此时网络请求还未返回,即使后续服务端状态更新,本次判断也不会用到最新数据。onBindViewHolder中调用ibadah_item_chechbox.setChecked()会自动触发你设置的OnCheckedChangeListener,列表滑动重绑item时也会意外触发弹窗逻辑。
修复方案
- 移除
onBindViewHolder中的ibadahs_isCompleted = ArrayList()代码,状态列表仅在getIbadahsList接口返回数据时初始化一次即可,你也可以直接废弃这个额外维护的状态列表,直接遍历ibadahslist判断全选状态即可,避免数据不同步。 - 触发Checkbox的选中回调后,先更新本地对应项的状态,再判断是否全选,不要依赖未完成的异步请求结果,同时先取消旧监听避免绑定item时意外触发回调:
// 适配器内增加弹窗标记位,避免重复弹窗 private var isDialogShown = false // 将ibadahslist改为MutableList支持本地更新状态 lateinit var ibadahslist: MutableList<Ibadah> override fun onBindViewHolder(holder: IbadahViewHolder, position: Int) { val currentItem = ibadahslist[position] holder.itemView.apply { ibadah_item_text.text = currentItem.ibadahText // 先移除旧监听避免绑定触发回调 ibadah_item_chechbox.setOnCheckedChangeListener(null) ibadah_item_chechbox.isChecked = currentItem.isComplete ibadah_item_chechbox.setOnCheckedChangeListener { _, isChecked -> // 更新本地状态 ibadahslist[position] = currentItem.copy(isComplete = isChecked) patchIbadah(position) // 直接遍历当前列表判断是否全部完成 val allCompleted = ibadahslist.all { it.isComplete } if (allCompleted && !isDialogShown) { AlertDialog.Builder(context) .setCancelable(true) .setView(R.layout.finish_ibadh) .setOnDismissListener { isDialogShown = false } .show() isDialogShown = true } } } }
- 对应修改
setQuranSurahList参数类型为MutableList<Ibadah>,或者在赋值时做一次转换即可。
内容的提问来源于stack exchange,提问作者Enigma
相关产品推荐
相关产品推荐

