RecyclerView не загружает никаких данных из Firebase и показывает null для всех строк. - PullRequest
1 голос
/ 04 августа 2020

[введите здесь описание изображения] [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

1 Ответ

0 голосов
/ 04 августа 2020

Хотя код полностью отформатирован и реализован, в приложении есть ошибка, которая не позволяет приложению извлекать и отображать данные.

Основная проблема в вашем коде находится в вашем классе Restaurants, где имя всех ваших геттеров неверно. Если в вашем классе есть свойство с именем id, соответствующий метод получения должен быть getId(), а не getRestaurantId(). С другой стороны, установщик должен быть setId() и , а не setRestaurantId(). Есть два способа решить эту проблему. Первый - изменить все имена всех геттеров / сеттеров в соответствии с приведенным выше примером.

Также обратите внимание, что сеттеры и геттеры не являются обязательными. Сеттеры всегда необязательны, потому что, если для свойства JSON нет сеттера, клиент 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
)

Обратите внимание, что имя class - это Restaurant, а не Restaurants, и это потому, что этот класс можно рассматривать как образец для одного ресторана, а не для нескольких ресторанов.

...