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

Android:Paging 3+Binding+Room集成后RecyclerView无数据显示求助

问题排查与修复方案

核心问题总结

你的代码存在三个关键错误,导致RecyclerView无法展示数据:

  1. Room DAO查询语句引用不存在的字段
  2. Paging3 Adapter实现逻辑冲突(混用PagingDataAdapter和AsyncListDiffer)
  3. Adapter的数据绑定逻辑与Paging3框架不匹配

1. Room DAO查询语句错误

错误点:AssetDao中getPagedAssetList方法使用ORDER BY page_key ASC,但AssetEntity并没有page_key字段,这会导致Room查询失败,PagingSource无法获取数据,且可能无明显报错日志。

修复方案:替换为AssetEntity中存在的字段(比如主键id):

@Dao
interface AssetDao {
    // ...其他方法
    @Query("SELECT * FROM tbl_assets ORDER BY id ASC ")
    fun getPagedAssetList(): PagingSource<Int,AssetEntity>
}

2. Paging3 Adapter实现逻辑冲突

错误点:你继承了Paging3官方的PagingDataAdapter,却自行实现了AsyncListDiffer,两者完全冲突。PagingDataAdapter内部已封装分页数据的加载与更新逻辑,额外的AsyncListDiffer会导致Fragment中调用的submitData无法将数据传递到正确数据源。

修复方案:删除所有AsyncListDiffer相关代码,直接使用PagingDataAdapter原生方法:

class AssetPageAdapter(private val interaction: Interaction? = null):
    PagingDataAdapter<AssetEntity, AssetPageAdapter.AssetViewHolder>(DIFF_CALLBACK) {

    companion object{
        val DIFF_CALLBACK : DiffUtil.ItemCallback<AssetEntity> = object : DiffUtil.ItemCallback<AssetEntity>(){
            override fun areItemsTheSame(oldItem: AssetEntity, newItem: AssetEntity): Boolean {
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(oldItem: AssetEntity, newItem: AssetEntity): Boolean {
                return oldItem == newItem
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : AssetViewHolder {
        val binding = RecyclerviewAssetBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        return AssetViewHolder(binding,interaction)
    }

    override fun onBindViewHolder(holder: AssetViewHolder, position: Int) {
        val item = getItem(position) ?: return // 处理Paging3占位符空值情况
        holder.bind(item)
    }

    inner class AssetViewHolder(
        val view: RecyclerviewAssetBinding,
        private val interaction: Interaction?
    ): RecyclerView.ViewHolder(view.root){

        fun bind(item: AssetEntity) {
            view.root.setOnClickListener {
                interaction?.onItemSelected(absoluteAdapterPosition,item)
            }
            view.assetDescription.text = item.description
            view.assetBarcode.text = item.barcode
        }
    }

    interface Interaction{
        fun onItemSelected(position: Int, item: AssetEntity)
    }
}

3. 数据库数据验证

必要检查:确保Room数据库中确实存在数据。可以通过Android Studio的Database Inspector工具查看tbl_assets表内容。如果数据为空,检查insertAssetList的调用逻辑:

  • 是否在协程中正确执行
  • 网络请求返回的数据是否成功映射为AssetEntity并写入数据库

额外优化建议

  • 若不需要占位符,将AssetListViewModel中PagingConfig的enablePlaceholders设为false,避免空占位问题
  • 在Fragment的collectLatest中添加日志,确认分页数据是否加载:
lifecycleScope.launch {
    viewModel.allAssets.collectLatest { pagingData ->
        pagingData.map { assets ->
            Log.d("AssetList", "加载到 ${assets.size} 条数据")
        }
        assetPageAdapter.submitData(pagingData)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:47:02