简体   繁体   English

为 RecyclerView 获取多个 Firestore 文档

[英]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,因为在ArrayListCategory类别之间,没有 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM