NestedScrollView内嵌RecyclerView仅显示1个条目 如何一次性展示全部条目
解决方案
核心原因是NestedScrollView和RecyclerView的测量逻辑存在冲突,ScrollView默认限制子控件的高度计算,导致RecyclerView的wrap_content属性无法正确计算所有条目总高度。
方案1:修改基础属性(优先尝试,无需自定义控件)
- 给
NestedScrollView添加android:fillViewport="true"属性,允许子布局填充ScrollView的可视区域,修改后的NestedScrollView代码如下:
<?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" android:background="@color/white" android:paddingBottom="52dp" android:fillViewport="true">
- 给RecyclerView添加
app:layout_constrainedHeight="true"属性,适配ConstraintLayout的测量规则:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/documents_rv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:paddingBottom="8dp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/title" app:layout_constraintTop_toBottomOf="@id/doc1" app:layout_constrainedHeight="true" tools:visibility="visible"/>
- 代码初始化RecyclerView时开启自动测量:
Kotlin示例:
documents_rv.layoutManager = LinearLayoutManager(this).apply { isAutoMeasureEnabled = true } // 条目高度固定的话添加以下代码提升性能 documents_rv.setHasFixedSize(true)
Java示例:
LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setAutoMeasureEnabled(true); documents_rv.setLayoutManager(layoutManager); // 条目高度固定的话添加以下代码提升性能 documents_rv.setHasFixedSize(true);
方案2:自定义不可滚动RecyclerView(兜底方案)
如果方案1不生效,直接重写RecyclerView的测量逻辑,强制计算所有条目的总高度:
Java版本自定义类
import android.content.Context; import android.util.AttributeSet; import android.view.View.MeasureSpec; import androidx.recyclerview.widget.RecyclerView; public class NoScrollRecyclerView extends RecyclerView { public NoScrollRecyclerView(Context context) { super(context); } public NoScrollRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public NoScrollRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
Kotlin版本自定义类
import android.content.Context import android.util.AttributeSet import android.view.View.MeasureSpec import androidx.recyclerview.widget.RecyclerView class NoScrollRecyclerView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : RecyclerView(context, attrs, defStyleAttr) { override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val expandSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE shr 2, MeasureSpec.AT_MOST) super.onMeasure(widthMeasureSpec, expandSpec) } }
布局替换
将布局中原RecyclerView的标签替换为自定义类的全路径即可,比如:
<com.yourpackage.name.NoScrollRecyclerView android:id="@+id/documents_rv" 其余属性保持不变.../>
条目布局优化建议
你当前的条目布局中TextView的layout_height设为了match_parent,虽然父布局是wrap_content的情况下可以正常生效,但建议改为wrap_content,测量逻辑更准确,避免潜在的高度计算问题。
内容的提问来源于stack exchange,提问作者skipperhi
相关产品推荐
相关产品推荐

