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

从FragmentB返回FragmentA后RecyclerView列表项不显示的问题

问题分析与解决方案

核心问题排查

返回FragmentA后RecyclerView为空,主要可能由以下几点导致:

  1. DiffUtil回调逻辑错误:BondedDeviceDiffItemCallback中用hashCode判断内容是否一致,若未重写BondedDevice的hashCode方法,会直接比较对象内存地址,导致ListAdapter无法正确识别列表项内容,进而不更新UI。
  2. 广播接收器注册时机错误:当前在onViewCreated注册、onDestroy注销接收器,Fragment被推入返回栈时不会触发onDestroy,导致重复注册接收器,可能干扰蓝牙设备状态获取。
  3. 生命周期收集时机问题:使用repeatOnLifecycle(Lifecycle.State.RESUMED)收集数据流,回到FragmentA时虽会重新触发收集,但如果数据加载未及时完成,可能短暂显示空列表。

针对性解决方案

1. 修正DiffUtil回调逻辑

将BondedDeviceDiffItemCallback的areContentsTheSame方法改为直接比较对象属性(若BondedDevice是data class,可直接用==):

class BondedDeviceDiffItemCallback : DiffUtil.ItemCallback<BondedDevice>() {
    override fun areItemsTheSame(oldItem: BondedDevice, newItem: BondedDevice): Boolean {
        return oldItem.address == newItem.address
    }

    override fun areContentsTheSame(oldItem: BondedDevice, newItem: BondedDevice): Boolean {
        // 若BondedDevice是data class,直接用oldItem == newItem即可
        return oldItem.name == newItem.name && oldItem.address == newItem.address
    }
}

2. 调整广播接收器的注册/注销时机

将接收器的注册移至onStart,注销移至onStop,避免重复注册:

@AndroidEntryPoint
class FragmentA : Fragment(R.layout.fragment_a) {
    // ... 其他代码

    override fun onStart() {
        super.onStart()
        requireActivity().registerReceiver(
            bluetoothStateBroadcastReceiver,
            IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
        )
    }

    override fun onStop() {
        super.onStop()
        try {
            requireActivity().unregisterReceiver(bluetoothStateBroadcastReceiver)
        } catch (ignored: Exception) {
        }
    }

    // 删除原onDestroy中的注销代码
}

3. 确保返回时重新加载数据

在repeatOnLifecycle的RESUMED块中主动触发数据加载,保证回到FragmentA时数据最新:

lifecycleScope.launch {
    viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
        // 每次进入前台时重新加载绑定设备
        loadBondedDevices()
        viewModel.uiData.collect { uiData: UIData ->
            if (uiData.bondedDevices.isEmpty()) {
                viewBinding.emptyMtv.visibility = View.VISIBLE
                viewBinding.recyclerView.visibility = View.GONE
            } else {
                viewBinding.emptyMtv.visibility = View.GONE
                viewBinding.recyclerView.visibility = View.VISIBLE
            }
            bondedDevicesAdapter.submitList(uiData.bondedDevices)
        }
    }
}

4. 确认UIData的初始化正确性

确保UIData的bondedDevices初始化为空列表,避免空指针或默认值异常:

data class UIData(val bondedDevices: List<BondedDevice> = emptyList())

额外建议

  • 在loadBondedDevices方法中添加日志,打印bluetoothAdapter.bondedDevices的大小,确认返回时是否能正确获取设备列表。
  • 若BondedDevice不是data class,建议重写equals和hashCode方法,保证对象比较逻辑的正确性。

内容的提问来源于stack exchange,提问作者dev.tejasb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:37:33