[tutaj wprowadź opis obrazu] [1]

Chociaż kod jest sformatowany i zaimplementowany całkowicie w porządku, wydaje się błąd w aplikacji, która nie pozwala aplikacji do pobrania i wyświetlania danych. Kompletne składniki końcówki używanej do budowy RecyclerView:

Fragment wyświetlający recyncleview:

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
            }
        })
    }
}

Użyto klasy modelu: -
.. Klasa modelu

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
    }
}

Użyto klasy adaptera: -
Klasa adaptera
..

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)
    }
}

Struktura bazy danych FireBase: [1]: https://i.stack.imgur.com/xdrxa.png.

1
Ayush 4 sierpień 2020, 05:28

1 odpowiedź

Najlepsza odpowiedź

Chociaż kod jest sformatowany i zaimplementowany całkowicie w porządku, wydaje się błąd w aplikacji, która nie pozwala aplikacji do pobrania i wyświetlania danych.

Główny problem w kodzie leży w klasie Restaurants, gdzie nazwa wszystkich getterów jest nieprawidłowy. Jeśli masz w swojej klasie właściwość o nazwie id, odpowiedni Getter powinien być getId() i nie getRestaurantId(). Z drugiej strony, seter powinien być setId() i nie setRestaurantId(). Istnieją dwa sposoby rozwiązywania tego problemu. Pierwszym byłoby zmianę wszystkich nazw wszystkich Galters / Setters zgodnie z powyższym przykładem.

Należy również pamiętać, że osadnicy i Getters nie są obowiązkowe. Setektory są zawsze opcjonalne, ponieważ jeśli nie ma setera dla właściwości JSON, klient FireBase ustawia wartość bezpośrednio na polu. Jednak prostszy sposób, w jaki można utworzyć taką klasę, jest zdefiniowana i zainicjować właściwości bezpośrednio do konstruktora i ustaw klasę jako 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
)

Należy również pamiętać, że nazwa klasy jest Restaurant i nie Restaurants, a to dlatego, że ta klasa może być uważana za plan do pojedynczej restauracji, a nie więcej restauracji .

1
Alex Mamo 4 sierpień 2020, 07:50