我正在尝试将 RecyclerView 添加到片段,但没有成功。我已经遵循了thisguide,但是其中RecyclerView被添加到MainActivity中,所以我尝试调整它。但是,我无法显示 RecyclerView。
我已经看过类似的问题,例如this one。
这是 RecyclerView 应该出现的
fragment_add_recipe.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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=".AddRecipeFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/recipe_name_text_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/recipe_name_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:inputType="text"
android:hint="@string/recipe_name_hint"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ingredient_row_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:itemCount="5"
tools:listitem="@layout/ingredient_row_view"
app:layout_constraintTop_toBottomOf="@id/recipe_name_text_input_layout"/>
<Button
android:id="@+id/save_recipe_button"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20sp"
android:text="Save"
android:textColor="#ffffff"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/ingredient_row_recycler_view"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
AddRecipeFragment.kt
:
package com.example.recipy
import CustomAdapter
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.recipy.databinding.FragmentAddRecipeBinding
class AddRecipeFragment : Fragment() {
private var _binding: FragmentAddRecipeBinding? = null
// For the ingredient row
private val ingredientList : ArrayList<IngredientRowViewModel> = ArrayList()
private lateinit var customAdapter : CustomAdapter
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the Fragment layout
_binding = FragmentAddRecipeBinding.inflate(inflater, container, false)
setAdapter()
return binding.root
}
private fun setAdapter(){
customAdapter = CustomAdapter(ingredientList)
binding.ingredientRowRecyclerView.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = customAdapter
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Make button save the recipe in the SQL db
binding.saveRecipeButton.setOnClickListener{
// Some code for SQL connection here
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
IngredientRowViewModel.kt
:
package com.example.recipy
data class IngredientRowViewModel(var ingredient: String) {
}
CustomAdapter.kt
:
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.recipy.IngredientRowViewModel
import com.example.recipy.R
import com.example.recipy.databinding.IngredientRowViewBinding
class CustomAdapter(private val ingredientList: ArrayList<IngredientRowViewModel>) : RecyclerView.Adapter<CustomAdapter.IngredientRowViewHolder>() {
inner class IngredientRowViewHolder(private val binding : IngredientRowViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(ingredient : IngredientRowViewModel){
binding.ingredient = ingredient
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IngredientRowViewHolder =
IngredientRowViewHolder(IngredientRowViewBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: IngredientRowViewHolder, position: Int) {
holder.bind(ingredientList[position])
}
override fun getItemCount(): Int {
return ingredientList.size
}
}
最后
ingredient_row_view.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="ingredient"
type="com.example.recipy.IngredientRowViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/ingredient_name_text_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ingredient_name_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:inputType="text"
android:hint="@string/ingredient_name_hint"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</layout>
我稍微更新了您的代码,正如我之前在评论中提到的,如果您想查看它,您必须向列表中添加一些项目。您可以添加按钮来添加项目,也可以使用固定大小的列表。
fragment_add_receipe.xml
添加新按钮,用于将成分添加到列表中。如果您不需要这个并且想要固定计数列表,只需创建包含空项目的列表,例如如下所示:
//This will show 5 empty text inputs in the recyclerView
private val ingredientList: ArrayList<IngredientRowViewModel> = arrayListOf(
IngredientRowViewModel(""),
IngredientRowViewModel(""),
IngredientRowViewModel(""),
IngredientRowViewModel(""),
IngredientRowViewModel(""),
)
fragment_add_receipe.xml 带有新按钮:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
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=".AddRecipeFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/recipe_name_text_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/recipe_name_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Receipe name"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ingredient_row_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@id/recipe_name_text_input_layout"
tools:itemCount="5"
tools:listitem="@layout/ingredient_row_view" />
<!-- Add new button so you can add ingredients into your list -->
<Button
android:id="@+id/addIngredient"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20sp"
android:text="Add Ingredient"
android:textColor="#ffffff"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/ingredient_row_recycler_view" />
<Button
android:id="@+id/save_recipe_button"
android:layout_width="150sp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20sp"
android:text="Save"
android:textColor="#ffffff"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/addIngredient" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
添加RecipeFragment.kt
将
onClickListener
设置为 addIngredient Button
并在添加新成分时通知您的适配器。添加后,RecyclerView
将显示一项(或多项),其中 TextField
为空。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.addIngredient.setOnClickListener {
//add new ingredient with empty name into your list so your item will be shown
ingredientList.add(IngredientRowViewModel(ingredient = ""))
//Use notifyItemInserted instead of notifyDataSetChanged for better performance
if (ingredientList.size == 0)
customAdapter.notifyItemInserted(0)
else
customAdapter.notifyItemInserted(ingredientList.size - 1)
}
...
}
ingredient_row_view.xml
这只是可选的,您有
android:layout_height="match_parent"
,这意味着单个项目将占用大量空间,并且您必须滚动才能看到第二个项目,您应该将其更改为 wrap_content
。
建议