Android LiveData 实现列表勾选

文章目录

    界面功能

    界面功能是禁忌症确认,只有不存在任何一项的时候,才能进入使用。

    每一项是一个 Switch 按钮,代表是否勾选。

    记录目的

    感觉我对 LiveData 的理解还是不够充分。也许经历越多的实战,才能理解更多吧。

    修改其中一个 item 的 field

    class ViewHolder(private val binding: ConfirmRowItemBinding) :
    	RecyclerView.ViewHolder(binding.root) {
    
    	fun bind(item: ConfirmationItem) {
    		binding.name.text = item.title
    		binding.switchOne.isChecked = item.isSelected
    		binding.switchOne.setOnCheckedChangeListener { _, isChecked ->
    			item.isSelected = isChecked
    		}
    	}
    }
    

    在 adapter 中,监听 switch 的切换,并赋值给 list item。

    实际上读取 live data 的 value 就能查询到最新状态了。

    全量修改

    binding.switchAll.setOnCheckedChangeListener { _, isChecked ->
    	val items = viewModel.items.value
    	items?.let { items ->
    		for (item in items) {
    			item.isSelected = isChecked
    		}
    	}
    	diseaseViewModel.items.postValue(items)
    	adapter.notifyDataSetChanged()
    }
    

    虽然 Android Studio 中提示:

    It will always be more efficient to use more specific change events if you can. Rely on notifyDataSetChanged as a last resort.

    但是这里,不用 notifyDataSetChanged 不行。

    DiffUtil 为何没有生效

    使用 DiffUtil 就是为了避免使用 recyclerview 的 adapter 的 notifyDataSetChanged(),因为当可能只有几件事情发生变化时,它重新绘制整个UI是不高效的。

    但是为何没有生效,我毫无头绪。。。

    关于 RecyclerView 的数据更新,主要有以下几个方法

    • notifyDataSetChanged(),刷新全部可见的item。
    • notifyItemChanged(int),刷新指定item。
    • notifyItemRangeChanged(int,int),从指定位置开始刷新指定个item。
    • notifyItemInserted(int)、notifyItemMoved(int)、notifyItemRemoved(int)。插入、移动一个并自动刷新。
    • notifyItemChanged(int, Object),局部刷新。

    为何监听 LiveData 监测不到 field 变化

    但是之前写的蓝牙扫描功能,就能实现显示信号强弱。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式