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

互斥下拉菜单场景下调用notifyDataSetChanged后RecyclerView尺寸不更新问题

效果演示图

预期实现效果

多个下拉菜单实现互斥选择,规则示例如下:

  • 可选数组 array = ["A", "B", "C", "D", "E"]
  • 共3个下拉菜单:menu1、menu2、menu3
  • 如果在menu1中选中"A",则menu2和menu3的选项列表中不再展示"A"

问题根因

你打印的dropdownMenu.size调用的是Android View类的size属性,返回的是视图的宽高尺寸,不是RecyclerView的列表项数量,应该取adapter.itemCount获取列表项总数。
除此之外,你的代码还有几处逻辑错误导致RecyclerView不刷新:


1. Adapter的setData方法更新顺序错误

当前你是先清空数据集、调用notify、再添加新数据,顺序不对,应该先更新数据集,再调用刷新通知。
修改ScddAdapter的setData方法:

fun setData(datas: ArrayList<String>) {
    list.clear()
    list.addAll(datas)
    // 数据集更新完成后再发刷新通知
    notifyDataSetChanged()
}

2. 选中状态没有和Adapter绑定

你之前直接操作RecyclerView的子View修改CheckBox选中状态,没有把选中状态存在Adapter里,RecyclerView刷新的时候状态就会丢失,同时也会导致视图不更新。
首先修改ScddAdapter:

  • 新增按值设置选中的方法
  • 绑定ViewHolder的时候同步设置CheckBox的选中状态
class ScddAdapter : RecyclerView.Adapter<ScddAdapter.ScddViewHolder>() {
    // ... 原有代码保持不变
    override fun onBindViewHolder(holder: ScddViewHolder, position: Int) {
        holder.cb.text = list[position]
        // 绑定的时候同步设置选中状态
        holder.cb.isChecked = position == checked
        holder.itemView.setOnClickListener {
            holder.cb.isChecked = !holder.cb.isChecked
            if(holder.cb.isChecked) {
                checkedStr = holder.cb.text as String
                checked = holder.layoutPosition
            } else {
                checkedStr = ""
                checked = -1
            }
            this.callback()
        }
    }

    // 新增按值设置选中的方法
    fun setCheckedByValue(value: CharSequence) {
        checkedStr = value
        checked = if(value.isEmpty()) -1 else list.indexOf(value)
        notifyDataSetChanged()
    }
    // ... 原有代码保持不变
}

然后修改SingleCheckBoxDropDown的setChecked方法,不要直接操作子View,通过Adapter更新状态:

fun setChecked(filter: CharSequence) {
    adapter.setCheckedByValue(filter)
}

3. 单选逻辑冗余

原来的点击事件里遍历RecyclerView子View修改选中状态的逻辑完全不需要,Adapter已经存储了选中位置,刷新后会自动更新所有子项的状态,修改setOnItemClickListenerWithSingleSelect方法:

fun setOnItemClickListenerWithSingleSelect(function: () -> Unit) {
    adapter.setOnItemClickListener {
        // 单选逻辑由Adapter的选中状态控制,刷新即可
        adapter.notifyDataSetChanged()
        function()
    }
}

修改完成后,RecyclerView就可以正常刷新,互斥选择逻辑也能正常运行。

内容的提问来源于stack exchange,提问作者Jakkins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:36:00