API 正在获取所有 JSON 数据,但我的应用程序在回收站视图中只显示一个数据,我该怎么办?

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

我正在使用食谱搜索 API 制作一个简单的食谱搜索应用程序,但问题是该应用程序从 API 获取所有数据,但我的应用程序在回收站视图中只显示一个,那么我应该怎么办做?请帮忙

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

日志

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

应用图片

Here is the image that displays only one item

食谱项目布局

<?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(数据class)

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

Hit.kt(数据class)

 data class Hit(
        val recipe: Recipe
    )

Recipe.kt(数据class)

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

在您的适配器中,您试图获得 recipesList 尺寸,其中仅包含一项 hits

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

我认为您需要使用 recipesList.hits.size 而不是 recipesList.size

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