【问题标题】:The RecyclerView doesn't load any data from Firebase and shows null for all the rowsRecyclerView 不会从 Firebase 加载任何数据,并且所有行都显示为 null
【发布时间】:2020-11-24 02:35:12
【问题描述】:

[在此处输入图片描述][1]

尽管代码的格式和实现完全正常,但应用程序中似乎存在一个错误,不允许应用程序检索和显示数据。用于构建RecyclerView的后端完整组件:

显示 RecyclerView 的片段:

package com.reazon.foodrunner.fragment

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.firebase.ui.database.FirebaseRecyclerAdapter
import com.google.firebase.database.*
import com.reazon.foodrunner.R
import com.reazon.foodrunner.adapter.HomeRecyclerAdapter
import com.reazon.foodrunner.model.Restaurants

class HomeFragment : Fragment() {

    private var mDatabaseReference: DatabaseReference? = null
    private var recyclerAdapter: HomeRecyclerAdapter? = null
    private var recyclerHome: RecyclerView? = null
    internal var restaurantsList: MutableList<Restaurants> = ArrayList()
    private var layoutManager: RecyclerView.LayoutManager? = null
    private lateinit var adapter: FirebaseRecyclerAdapter<Restaurants,HomeRecyclerAdapter.HomeRecyclerViewHolder>
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_home, container, false)
        mDatabaseReference = FirebaseDatabase.getInstance().getReference("Restaurants")
        recyclerHome = view.findViewById(R.id.recyclerHomeAll)

        layoutManager = LinearLayoutManager(activity)
        recyclerHome!!.layoutManager = layoutManager

        //retrieve data from firebase
        retrieveAllRestaurants()

        return view
    }

    private fun retrieveAllRestaurants() {
        restaurantsList.clear()
        val restaurantReference = FirebaseDatabase.getInstance().reference.child("Restaurants")

        restaurantReference.addValueEventListener(object : ValueEventListener {
            override fun onCancelled(error: DatabaseError) {
                Log.d("ERROR ", "" + error.message)
            }

            override fun onDataChange(p0: DataSnapshot) {
                for (snapshot in p0.children) {
                    val restaurant = snapshot.getValue(Restaurants::class.java)
                    restaurant!!.getRestaurant()
                    restaurant.getRestaurantRating()
                    restaurant.getCostForOne()
                    restaurant.getRestaurantName()

                    restaurantsList.add(restaurant)

                }
                recyclerAdapter = HomeRecyclerAdapter(context!! , restaurantsList)
                recyclerHome?.adapter = recyclerAdapter
            }
        })
    }
}

使用的模型类:-
模型类

package com.reazon.foodrunner.model

class Restaurants {
    private var id: String? = null
    private var name: String? = null
    private var rating: String? = null
    private var cost_for_one: String? = null
    private var imageUrl: String? = null

    constructor()

    constructor(
        id: String,
        name: String,
        rating: String,
        cost_for_one: String,
        imageUrl: String
    ) {
        this.id = id
        this.name = name
        this.rating = rating
        this.cost_for_one = cost_for_one
        this.imageUrl = imageUrl
    }

    fun getRestaurant(): String? {
        return imageUrl
    }

    fun setRestaurant(imageUrl: String){
        this.imageUrl = imageUrl
    }

    fun getRestaurantId(): String? {
        return id
    }

    fun setRestaurantId(id: String){
        this.id = id
    }

    fun getRestaurantName(): String? {
        return name
    }

    fun setRestaurantName(name: String){
        this.name = name
    }
    fun getRestaurantRating(): String? {
        return rating
    }
    fun setRestaurantRating(rating: String){
        this.rating = rating
    }

    fun getCostForOne(): String? {
        return cost_for_one
    }
    fun setCostForOne(cost_for_one: String) {
        this.cost_for_one = cost_for_one
    }
}

使用的适配器类:-
适配器类

package com.reazon.foodrunner.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.reazon.foodrunner.R
import com.reazon.foodrunner.model.Restaurants
import com.squareup.picasso.Picasso

class HomeRecyclerAdapter(
    var context: Context,
    var restaurantsList: List<Restaurants>
) : RecyclerView.Adapter<HomeRecyclerAdapter.HomeRecyclerViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeRecyclerViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.recycler_home_single_row, parent, false)
        return HomeRecyclerViewHolder(view)
    }

    override fun getItemCount(): Int {
        return restaurantsList.size
    }

    override fun onBindViewHolder(holder: HomeRecyclerViewHolder, position: Int) {
        val restaurant = restaurantsList[position]
        holder.costForOne.text = restaurant.getCostForOne().toString()
        holder.rating.text = restaurant.getRestaurantRating().toString()
        holder.textView.text = restaurant.getRestaurantName()
            Picasso.get().load(restaurant.getRestaurant()).placeholder(R.drawable.food_runner_icon).into(holder.imageView).toString() 
        holder.btnFavourite.setOnClickListener {
            Toast.makeText(context ,"Favourite Button Clicked",Toast.LENGTH_LONG).show()
        }
    }

    class HomeRecyclerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var imageView: ImageView = view.findViewById(R.id.imgRestaurantImage)
        var costForOne: TextView = view.findViewById(R.id.txtCostForOne)
        var textView: TextView = view.findViewById(R.id.txtRestaurantName)
        var btnFavourite: ImageButton = view.findViewById(R.id.btnFavourite)
        var rating: TextView = view.findViewById(R.id.txtRating)
    }
}

Firebase 数据库结构: [1]:https://i.stack.imgur.com/XDrxa.png

【问题讨论】:

  • 你能展示一下firebase数据库结构吗?
  • 是的,它是父“餐厅”i.stack.imgur.com/XDrxa.png987654322@ 中的一个列表

标签: firebase kotlin firebase-realtime-database android-recyclerview


【解决方案1】:

虽然代码的格式和实现完全没问题,但应用程序中似乎存在一个错误,不允许应用程序检索和显示数据。

您的代码中的主要问题在于您的 Restaurants 类,其中所有 getter 的名称都不正确。如果你的类中有一个名为id 的属性,则对应的getter 应该是getId()not getRestaurantId()。另一方面,setter 应该是 setId()not setRestaurantId()。有两种方法可以解决此问题。第一个是根据上面的示例更改所有 getter/setter 的所有名称。

另外请注意,setter 和 getter 不是强制性的。 Setter 始终是可选的,因为如果 JSON 属性没有 setter,Firebase 客户端会将值直接设置到字段中。但是,创建此类的更简单方法是直接在构造函数中定义和初始化属性,并将类设置为data class

data class Restaurant(
    var id: String? = null,
    var name: String? = null,
    var rating: String? = null,
    var cost_for_one: String? = null,
    var imageUrl: String? = null
)

还请注意,该课程的名称是Restaurant不是 Restaurants,这是因为该课程可以被视为单个餐厅的蓝图,而不是更多餐厅的蓝图。

【讨论】:

  • 我真的不知道如何感谢你,也不太明白更改变量如何优化代码,但解决方案有效。非常感谢。
  • 如果您认为我的回答对未来的 Firebase 开发者也有帮助,也请考虑投上一票(▲)。我真的很感激。谢谢!
猜你喜欢
  • 2019-11-02
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
相关资源
最近更新 更多