Home > other >  API is fetching all the JSON data but my app displays only one in recycler view what should i do?
API is fetching all the JSON data but my app displays only one in recycler view what should i do?

Time:03-02

I am making a simple recipe search app using recipe search API but the problem is the app fetches all the data from API but my app displays only one in recycler view then what should I do? Please help

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var recipeViewModel: RecipeViewModel
    lateinit var mainBinding: ActivityMainBinding
    lateinit var recipeAdapter: RecipeAdapter
    lateinit var recipeItemList: ArrayList<Recipes>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mainBinding.root)

        recipeViewModel =
            ViewModelProvider(
                this,
                ViewModelProvider.AndroidViewModelFactory
                    .getInstance(application)
            )[RecipeViewModel::class.java]

        recipeItemList = arrayListOf()
        mainBinding.recyclerView.layoutManager = LinearLayoutManager(this)

        recipeViewModel.recipeLiveData.observe(this, Observer { recipeItems ->
            recipeItemList.add(recipeItems)
            recipeAdapter = RecipeAdapter(this, recipeItemList)
            mainBinding.recyclerView.adapter = recipeAdapter
            Log.d("RESPONSE", recipeItems.toString())
            Log.d("List size", recipeAdapter.itemCount.toString())
        })

        searchRecipeName()

    }

    private fun searchRecipeName() {
        mainBinding.searchRecipeFabBtn.setOnClickListener {
            val view = layoutInflater.inflate(R.layout.recipe_search_layout, null)
            val searchRecipeET = view.findViewById<EditText>(R.id.searchRecipeET)
            val searchRecipeBtn = view.findViewById<Button>(R.id.searchRecipeBtn)
            val bottomSheetDialog = BottomSheetDialog(this)
            bottomSheetDialog.apply {
                this.setContentView(view)
                this.show()
            }

            searchRecipeBtn.setOnClickListener {
                val recipeName = searchRecipeET.text.toString()
                searchRecipeName(recipeName, searchRecipeET, bottomSheetDialog)
            }
        }
    }

    private fun searchRecipeName(
        recipeName: String,
        searchRecipeET: EditText,
        bottomSheetDialog: BottomSheetDialog
    ) {
        if (recipeName.isEmpty()) {
            searchRecipeET.error = "Please enter recipe name"
        } else {
            recipeViewModel.getRecipes(recipeName)
            bottomSheetDialog.dismiss()
        }
    }
} 

RecipeAdapter.kt

class RecipeAdapter(val context: Context, val recipesList: ArrayList<Recipes> = arrayListOf()) : RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder>() {


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

    override fun onBindViewHolder(holder: RecipeViewHolder, position: Int) {
        val currentItem = recipesList[position]
        holder.recipeImageView.load(currentItem.hits[3].recipe.image)
        holder.recipeNameText.text = currentItem.hits[4].recipe.label
    }

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

    class RecipeViewHolder(itemView: View) :RecyclerView.ViewHolder(itemView) {
        val recipeImageView: ImageView = itemView.findViewById(R.id.recipeImageView)
        val recipeNameText: TextView = itemView.findViewById(R.id.recipeNameText)
    }
}

RecipeViewModel.kt

class RecipeViewModel() : ViewModel() {

    private val recipeRepository: RecipeRepository =
        RecipeRepository(RetrofitInstance.provideApiService)

    val recipeLiveData: LiveData<Recipes>
        get() = recipeRepository.recipeLiveData

    fun getRecipes(q:String) = viewModelScope.launch {
       recipeRepository.getRecipes(q)
    }
}

RecipeRepository.kt

class RecipeRepository(private val apiService: ApiService) {

      private val recipeMutableLiveData: MutableLiveData<Recipes> = MutableLiveData()

      val recipeLiveData: LiveData<Recipes>
          get() = recipeMutableLiveData


    suspend fun getRecipes(q:String){
        val response = apiService.getRecipes(q)
        recipeMutableLiveData.value = response.body()
    }
} 

APIService.kt

interface ApiService {
    @GET("/api/recipes/v2?type=public&app_id=${APP_ID.appId}&app_key=${API_KEY.apiKey}")
    suspend fun getRecipes(@Query("q") q:String): Response<Recipes>
}

Logs

2022-03-01 17:06:00.267 14222-14222/com.yash1307.digitalrecipebook D/RESPONSE: Recipes(hits=[Hit(recipe=Recipe(calories=308.34999999999997, dietLabels=[Low-Carb, Low-Sodium], healthLabels=[Sugar-Conscious, Low Potassium, Kidney-Friendly, Keto-Friendly, Vegetarian, Pescatarian, Paleo, Mediterranean, Dairy-Free, Gluten-Free, Wheat-Free, Peanut-Free, Tree-Nut-Free, Soy-Free, Fish-Free, Shellfish-Free, Pork-Free, Red-Meat-Free, Crustacean-Free, Celery-Free, Mustard-Free, Sesame-Free, Lupine-Free, Mollusk-Free, Alcohol-Free, No oil added, Sulfite-Free, FODMAP-Free, Kosher], image=https://www.edamam.com/web-img/20f/20f0c2553240a2c6bc639d64df3f9df4.jpg, label=Poached Eggs, totalNutrients=TotalNutrients(CA=CAX(label=Calcium, quantity=120.69999999999999, unit=mg), CHOCDF=CHOCDFX(label=Carbs, quantity=1.5499999999999998, unit=g), CHOLE=CHOLEX(label=Cholesterol, quantity=799.8, unit=mg), ENERC_KCAL=ENERCKCALX(label=Energy, quantity=308.34999999999997, unit=kcal), FAT=FATX(label=Fat, quantity=20.4465, unit=g), FE=FEX(label=Iron, quantity=3.764, unit=mg), K=KX(label=Potassium, quantity=296.8, unit=mg), MG=MGX(label=Magnesium, quantity=25.849999999999998, unit=mg), NA=NAX(label=Sodium, quantity=305.40000000000003, unit=mg), PROCNT=PROCNTX(label=Protein, quantity=27.004, unit=g)))), Hit(recipe=Recipe(calories=786.91, dietLabels=[Low-Carb], healthLabels=[Sugar-Conscious, Low Potassium, Kidney-Friendly, Vegetarian, Pescatarian, Peanut-Free, Tree-Nut-Free, Soy-Free, Fish-Free, Shellfish-Free, Pork-Free, Red-Meat-Free, Crustacean-Free, Celery-Free, Mustard-Free, Sesame-Free, Lupine-Free, Mollusk-Free, Alcohol-Free, Sulfite-Free, Kosher, Immuno-Supportive], image=https://www.edamam.com/web-img/943/943f98393348d0daf5f239e328c0bb5d.jpg, label=Moonstruck eggs, totalNutrients=TotalNutrients(CA=CAX(label=Calcium, quantity=142.34, unit=mg), CHOCDF=CHOCDFX(label=Carbs, quantity=28.896199999999997, unit=g), CHOLE=CHOLEX(label=Cholesterol, quantity=472.57000000000005, unit=mg), ENERC_KCAL=ENERCKCALX(label=Energy, quantity=786.91, unit=kcal), FAT=FATX(label=Fat, quantity=67.6459, unit=g), FE=FEX(label=Iron, quantity=3.5434, unit=mg), K=KX(label=Potassium, quantity=238.37999999999997, unit=mg), MG=MGX(label=Magnesium, quantity=37.84, unit=mg), NA=NAX(label=Sodium, quantity=424.57, unit=mg), PROCNT=PROCNTX(label=Protein, quantity=17.622700000000002, unit=g)))), Hit(recipe=Recipe(calories=451.61312499999997, dietLabels=[], healthLabels=[Sugar-Conscious, Low Potassium, Kidney-Friendly, Keto-Friendly, Vegetarian, Pescatarian, Mediterranean, Dairy-Free, Peanut-Free, Tree-Nut-Free, Soy-Free, Fish-Free, Shellfish-Free, Pork-Free, Red-Meat-Free, Crustacean-Free, Celery-Free, Mustard-Free, Sesame-Free, Lupine-Free, Mollusk-Free, Alcohol-Free, Sulfite-Free, Kosher], image=https://www.edamam.com/web-img/558/558ccc3d6e43aaf065322133ad6287b0.jpg, label=Poached Eggs, totalNutrients=TotalNutrients(CA=CAX(label=Calcium, quantity=197.9872197236699, unit=mg), CHOCDF=CHOCDFX(label=Carbs, quantity=29.56533125, unit=g), CHOLE=CHOLEX(label=Cholesterol, quantity=744.0, unit=mg), ENERC_KCAL=ENERCKCALX(label=Energy, quantity=451.61312499999997, unit=kcal), FAT=FATX(label=Fat, quantity=21.014962499999996, unit=g), FE=FEX(label=Iron, quantity=5.603875052450463, unit=mg), K=KX(label=Potassium, quantity=394.53073990789, unit=mg), MG=MGX(label=Magnesium, quantity=53.41204561348624, unit=mg), NA=NAX(label=Sodium, quantity=728.8926375, unit=mg), PROCNT=PROCNTX(label=Protein, quantity=31.436606249999997, unit=g)))), Hit(recipe=Recipe(calories=2863.0874999990874, dietLabels=[Low-Carb], healthLabels=[Sugar-Conscious, Peanut-Free, Tree-Nut-Free, Soy-Free, Fish-Free, Shellfish-Free, Crustacean-Free, Celery-Free, Mustard-Free, Sesame-Free, Lupine-Free, Mollusk-Free, Alcohol-Free, Sulfite-Free], image=https://www.edamam.com/web-img/48a/48ae883aa945c01b0b8c590d40e6fd34.jpg, label=Eggs Benedict, totalNutrients=TotalNutrients(CA=CAX(label=Calcium, quantity=584.8499999983388, unit=mg), CHOCDF=CHOCDFX(label=Carbs, quantity=89.18834999989487, unit=g), CHOLE=CHOLEX(label=Cholesterol, quantity=1377.6524999998987, unit=mg), ENERC_KCAL=EN

App image

Here is the image that displays only one item

Recipe Items Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.google.android.material.card.MaterialCardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="6dp"
        app:cardElevation="6dp"
        app:cardUseCompatPadding="true">

        <ImageView
            android:id="@ id/recipeImageView"
            android:layout_width="140dp"
            android:layout_height="140dp"
            android:scaleType="centerCrop"
            android:src="@drawable/ic_baseline_search_24" />

        <TextView
            android:id="@ id/recipeNameText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginStart="12dp"
            android:textSize="20sp"
            tools:text="Recipe Name" />

    </com.google.android.material.card.MaterialCardView>


</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@ id/recyclerView"
        android:layout_width="409dp"
        android:layout_height="729dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@ id/searchRecipeFabBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="@ id/recyclerView"
        app:layout_constraintEnd_toEndOf="@ id/recyclerView"
        app:layout_constraintHorizontal_bias="0.957"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@ id/recyclerView"
        app:layout_constraintVertical_bias="0.950"
        app:srcCompat="@drawable/ic_baseline_search_24"
        android:focusable="true"
        android:contentDescription="@string/search_recipes" />

</androidx.constraintlayout.widget.ConstraintLayout>

Reicpes.kt (data class)

data class Recipes(
    val hits: ArrayList<Hit>,
)

Hit.kt (data class)

 data class Hit(
        val recipe: Recipe
    )

Recipe.kt (data class)

data class Recipe(
    val calories: Double,
    val dietLabels: List<String>,
    val healthLabels: List<String>,
    val image: String,
    val label: String,
    val totalNutrients: TotalNutrients,
)

CodePudding user response:

in your Adapter you trying to get recipesList size which is contain only one item hits in it

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

I think you need to use recipesList.hits.size instead of recipesList.size

override fun getItemCount(): Int {
       return recipesList.hits.size
    }
  • Related