RecyclerView加载Cloud Firestore数据不显示,本地模拟数据正常如何解决?
问题根本原因
Firestore 的 collection.get() 是异步执行的,你在 onCreate 中调用 populateList() 初始化列表时,Firestore 网络请求还没有返回结果,此时传给适配器的 imageModelArrayList 是空列表。后续请求成功把数据添加到列表后,你没有主动通知适配器数据发生了变更,RecyclerView 不会自动刷新渲染,所以就出现了加载不出来的情况。
而硬编码构造数据可以正常运行,是因为硬编码逻辑是同步执行的,实例化适配器时列表里已经有完整数据,所以可以正常渲染。
修复步骤
1. 调整变量作用域
把适配器和承载数据的列表改为Activity的类成员变量,不要在onCreate里定义成局部变量,方便你在Firestore的异步回调中访问:
// 类内部定义成员变量 private lateinit var mAdapter: Adapter private val imageModelArrayList = arrayListOf<Model>()
2. 调整初始化逻辑
onCreate中先初始化RecyclerView和适配器,再触发Firestore数据请求:
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) // 初始化适配器,此时列表为空也没关系 mAdapter = Adapter(imageModelArrayList) recyclerView.adapter = mAdapter // 触发Firestore数据加载 loadFirestoreData()
3. 异步请求完成后通知适配器刷新
Firestore请求成功、所有数据写入列表后,调用适配器的刷新方法:
private fun loadFirestoreData() { collection.get().addOnSuccessListener { querySnapshot -> // 先清空旧数据,避免重复添加 imageModelArrayList.clear() for (document in querySnapshot.documents) { val data = document.data ?: continue val model = Model() model.Name = data["Name"].toString() model.Rating = data["Rating"].toString().toFloat() imageModelArrayList.add(model) } // 通知适配器数据变更,触发RecyclerView重绘 mAdapter.notifyDataSetChanged() } }
可选优化
你之前尝试的toObject<Model>()方法是可以正常使用的,只要你的Model类满足Firestore序列化要求:有公开的无参构造方法、字段名和Firestore存储的字段名完全匹配、字段有对应的get/set方法,不需要手动从HashMap逐个取值,代码会更简洁。
内容的提问来源于stack exchange,提问作者Bennettleben
相关产品推荐
相关产品推荐

