Android Spinner加载Room数据库数据出现重复条目如何解决?
问题根源
你遇到的重复条目问题由三个常见原因共同导致:
- LiveData默认存在粘性回调特性,当页面回到前台变为活跃状态时,会再次收到之前已经发送过的最新设备列表数据
- 你在LiveData的观察回调中直接往Adapter追加数据,没有先清空旧数据,每次收到回调都会多添加一遍已存在的条目
- 如果你把
initSpinnerData()放到onResume中调用,还会导致重复注册LiveData观察者,同一次数据更新会触发多次回调,多次追加数据进一步加剧重复问题
修复方案
- 把
initSpinnerData()的调用移回onCreate方法,只在页面初始化时执行一次,避免重复注册观察者 - 在LiveData回调添加数据前,先调用
clear()清空Adapter中已有的旧数据,每次都做全量刷新 - 优化Adapter初始化的空安全调用逻辑,减少冗余判断
修改后的代码示例
private fun initSpinnerData(){ // 初始化Adapter,仅在页面创建时执行一次 val allDevices = ArrayAdapter<Any>(this, R.layout.simple_item_spinner, R.id.tv_simple_item) spinner3.adapter = allDevices // 注册Room数据观察者,仅注册一次,Lifecycle会自动管理观察者生命周期 zebraViewModel.getAllZebra().observe(this, { devices -> // 先清空旧数据,再添加新查询到的数据集,避免追加重复 allDevices.clear() devices?.forEach { allDevices.add(it) } } ) spinner3.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ override fun onItemSelected(parent: AdapterView<*>?, p1: View?, position: Int, p3: Long) { parent?.let { val idZebraString = it.getItemAtPosition(position).toString() idZebra = idZebraString.toInt() } } override fun onNothingSelected(p0: AdapterView<*>?) { Toast.makeText(this@ZebraActivity, "You must choose some item", Toast.LENGTH_LONG).show() } } }
如果按上述修改后仍存在重复问题,可以排查Room的查询逻辑是否存在重复返回相同条目的问题,以及ViewModel中getAllZebra()返回的LiveData是否存在多次发射重复数据的逻辑。
内容的提问来源于stack exchange,提问作者jenik2205
相关产品推荐
相关产品推荐

