Fragment中RecyclerView无法显示的问题求助
Fragment中RecyclerView无法显示的问题求助
大家好,我尝试在Fragment里添加RecyclerView但一直没成功,跟着原本适配MainActivity的教程改了代码,可RecyclerView就是不显示。已经查过类似问题还是没解决,麻烦帮我看看哪里出问题了。
我的布局和代码如下:
fragment_add_recipe.xml(RecyclerView所在布局)
<?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>
我排查到的几个可能问题及解决办法:
问题1:RecyclerView的数据源是空的
你的ingredientList初始化后没有添加任何数据,CustomAdapter的getItemCount()返回0,RecyclerView自然没有内容可显示。可以先手动加几条测试数据试试:private fun setAdapter(){ // 先添加测试数据 ingredientList.add(IngredientRowViewModel("鸡蛋")) ingredientList.add(IngredientRowViewModel("面粉")) customAdapter = CustomAdapter(ingredientList) binding.ingredientRowRecyclerView.apply { layoutManager = LinearLayoutManager(requireContext()) adapter = customAdapter } }问题2:RecyclerView的布局约束和高度设置有问题
你的RecyclerView在ConstraintLayout里设置了android:layout_height="match_parent",同时外层是NestedScrollView,这会导致RecyclerView无限延伸,把下方的Save按钮挤出去,而且本身也无法正确计算高度。建议修改RecyclerView的布局属性:<androidx.recyclerview.widget.RecyclerView android:id="@+id/ingredient_row_recycler_view" android:layout_width="match_parent" android:layout_height="0dp" <!-- 改成0dp,用约束控制高度 --> tools:itemCount="5" tools:listitem="@layout/ingredient_row_view" app:layout_constraintTop_toBottomOf="@id/recipe_name_text_input_layout" app:layout_constraintBottom_toTopOf="@id/save_recipe_button" <!-- 添加底部约束,和按钮隔开 --> app:layout_constraintVertical_bias="0" />另外,NestedScrollView里的ConstraintLayout高度可以改成
wrap_content,避免不必要的滚动冲突。问题3:数据绑定未正确关联到EditText
你的ingredient_row_view.xml里的TextInputEditText没有绑定ingredient的ingredient字段,即使有数据也不会显示。需要给EditText加上绑定:<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" android:text="@{ingredient.ingredient}" <!-- 添加这行数据绑定 --> app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/>
备注:内容来源于stack exchange,提问作者gitcanzo
相关产品推荐
相关产品推荐

