[英]Fetching Multiple Firestore Documents for RecyclerView
I'm trying to fetch multiple documents from my Firestore collection so I can populate my RecyclerView.我正在尝试从我的 Firestore 集合中获取多个文档,以便填充我的 RecyclerView。 However, I'm getting a mismatch error when I try to hook my
categories
ArrayList to the QuerySnapshot, it says it's looking for kotlin.collections.ArrayList<Category>
but it found Category?
但是,当我尝试将我的
categories
ArrayList 挂接到 QuerySnapshot 时出现不匹配错误,它说它正在寻找kotlin.collections.ArrayList<Category>
但找到了Category?
. . What can I do to make my RecyclerView populate my category collection in Firestore?
我可以做些什么来让我的 RecyclerView 填充我在 Firestore 中的类别集合? Do I need to rewrite my
val categories = ArrayList<Category>()
?我需要重写我的
val categories = ArrayList<Category>()
吗? Thank you!谢谢!
Category Collection类别集合
Category.kt类别.kt
data class Category(var category: String?, val categoryImage: String?) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(category)
parcel.writeString(categoryImage)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Category> {
override fun createFromParcel(parcel: Parcel): Category {
return Category(parcel)
}
override fun newArray(size: Int): Array<Category?> {
return arrayOfNulls(size)
}
}
}
CategoryAdapter.kt类别适配器.kt
class CategoryAdapter(val category: ArrayList<Category>) : RecyclerView.Adapter<CategoryAdapter.ViewHolder>() {
var selectedCategory = Category("", "")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindCategory(category[position])
holder.itemView.setOnClickListener { v ->
val context: Context = v.context
val intent = Intent(context, CategoryServiceActivity::class.java)
selectedCategory.category = category[position].category
intent.putExtra("category", selectedCategory)
context.startActivity(intent)
}
}
override fun getItemCount(): Int {
return category.count()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.categoryrecyclyerview, parent, false)
return ViewHolder(view)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val categoryName = itemView.findViewById<TextView>(R.id.categoryJobNameTextView)
val categoryImage = itemView.findViewById<ImageView>(R.id.categoryImageView)
fun bindCategory(category: Category) {
categoryName?.text = category.category
Picasso.get().load(category.categoryImage).into(categoryImage)
}
}
}
HomeFragment.kt HomeFragment.kt
val categories = ArrayList<Category>()
val categoriesDatabaseRef = FirebaseFirestore.getInstance().collection(REF_JOB_CATEGORIES)
categoriesDatabaseRef.orderBy("category").get().addOnSuccessListener(object: OnSuccessListener<QuerySnapshot> {
override fun onSuccess(p0: QuerySnapshot?) {
if (p0 != null) {
for (querySnapshot in p0.documents) {
categories = querySnapshot.toObject(Category::class.java)
}
}
}
})
As I see in your code, the categories
object is an ArrayList
.正如我在您的代码中看到的那样,
categories
object 是ArrayList
。 So when you're using the following line of code:因此,当您使用以下代码行时:
categories = querySnapshot.toObject(Category::class.java)
It means that you're trying to convert the querySnapshot
object, which is actually a DocumentSnapshot object, into an object of type Category
, which works perfectly fine.这意味着您正在尝试将
querySnapshot
object(实际上是DocumentSnapshot object)转换为Category
为 object 的类型,效果很好。 However, you cannot assign that value to the categories
object because between the ArrayList
and Category
classes, there is no inheritance relationship, hence that error.但是,您不能将该值分配给
categories
object,因为在ArrayList
和Category
类别之间,没有 inheritance 关系,因此出现该错误。
So there are two ways in which you can solve this.所以有两种方法可以解决这个问题。 The first solution would be to add an object of type
Category
, at each iteration of the for loop to the list:第一个解决方案是在 for 循环的每次迭代中将类型为
Category
的 object 添加到列表中:
categoriesDatabaseRef.orderBy("category").get().addOnSuccessListener(object: OnSuccessListener<QuerySnapshot> {
override fun onSuccess(p0: QuerySnapshot?) {
if (p0 != null) {
for (querySnapshot in p0.documents) {
val category = querySnapshot.toObject(Category::class.java)
categories.add(category) //Add the object to the list.
}
}
}
})
The second solution, which is even simpler in my opinion, would be to convert the querySnapshot
directly into a list, by removing the for loop like this:第二种解决方案,在我看来更简单,将
querySnapshot
直接转换为列表,方法是删除 for 循环,如下所示:
categoriesDatabaseRef.orderBy("category").get().addOnSuccessListener(object: OnSuccessListener<QuerySnapshot> {
override fun onSuccess(p0: QuerySnapshot?) {
if (p0 != null) {
categories = p0.toObjects(Category::class.java)
}
}
})
Please see that I have used toObjects(Class clazz) method which:请查看我使用的 toObjects(Class clazz)方法:
Returns the contents of the documents in the QuerySnapshot, converted to the provided class, as a list.
返回 QuerySnapshot 中文档的内容,转换为提供的 class,作为列表。
So it's toObjects
, see the s
?所以它是
toObjects
,看到s
了吗? And not toObject
.而不是
toObject
。
Besides that, don't forget that Firebase API is asynchronous.除此之外,别忘了 Firebase API 是异步的。 So you cannot simply use the value of
categories
outside the onSuccess()
method.因此,您不能简单地使用
onSuccess()
方法之外的categories
值。 If you're new to asynchronous programming, I recommend you read the following resource:如果您不熟悉异步编程,我建议您阅读以下资源:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.