You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ScrollView嵌套两个RecyclerView时如何让第二个RecyclerView显示全部内容

解决ScrollView嵌套RecyclerView时第二个RecyclerView只显示一条数据的问题

嘿,我之前踩过一模一样的坑!当把RecyclerView嵌套在ScrollView里,并且给RecyclerView设置android:layout_height="wrap_content"时,很容易出现这种高度计算不准的情况,尤其是你用的旧版Android Support库(android.support.v7.widget.RecyclerView),这个问题在旧版里特别常见。

问题原因

ScrollView的测量逻辑是让子View尽可能适应它的可用空间,而旧版RecyclerView在wrap_content模式下,无法正确计算出所有列表项的总高度,只会计算当前可见部分的高度。第二个RecyclerView因为处于ScrollView的下方,这种高度计算偏差会被放大,导致只显示一条数据。

解决方案(三种方法,按推荐程度排序)

1. 升级到AndroidX RecyclerView(最推荐)

新版的AndroidX库已经修复了wrap_content在ScrollView中的高度计算问题,只需要把你的依赖和XML标签换成AndroidX版本即可:

  • 替换依赖(在build.gradle里):
    implementation 'androidx.recyclerview:recyclerview:1.3.2' // 用最新版本即可
    
  • 替换XML里的RecyclerView标签:
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/newsInfonitas"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" />
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/newsIndoChina"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" />
    
    这样不用改任何Java/Kotlin代码,就能让两个RecyclerView都正常显示所有数据。

2. 自定义RecyclerView重写onMeasure方法(兼容旧版Support库)

如果暂时不能升级到AndroidX,可以自定义一个RecyclerView,强制它计算所有条目的总高度:

public class FullHeightRecyclerView extends RecyclerView {
    public FullHeightRecyclerView(Context context) {
        super(context);
    }

    public FullHeightRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FullHeightRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        // 强制RecyclerView计算所有条目的总高度,而不是只算可见部分
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthSpec, expandSpec);
    }
}

然后把XML里的android.support.v7.widget.RecyclerView换成你自定义的这个类:

<com.udaily.udaily.view.widget.FullHeightRecyclerView
    android:id="@+id/newsInfonitas"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" />

<com.udaily.udaily.view.widget.FullHeightRecyclerView
    android:id="@+id/newsIndoChina"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" />

(注意替换成你自己的包路径)

3. 手动计算RecyclerView高度(不推荐,仅作备选)

如果上面两种方法都用不了,可以在Adapter设置数据后,手动计算所有item的高度总和,然后设置给RecyclerView:

// 假设你的RecyclerView是newsIndoChina,Adapter是adapter
newsIndoChina.post(() -> {
    int totalHeight = 0;
    for (int i = 0; i < adapter.getItemCount(); i++) {
        View itemView = adapter.createViewHolder(newsIndoChina, adapter.getItemViewType(i)).itemView;
        itemView.measure(View.MeasureSpec.makeMeasureSpec(newsIndoChina.getWidth(), View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        totalHeight += itemView.getMeasuredHeight();
    }
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) newsIndoChina.getLayoutParams();
    params.height = totalHeight + newsIndoChina.getPaddingTop() + newsIndoChina.getPaddingBottom();
    newsIndoChina.setLayoutParams(params);
});

这种方法的缺点是如果item高度不固定(比如有文本换行),计算会不准确,而且代码比较繁琐,所以优先推荐前两种方法。

额外优化建议

为了让滚动体验更好,可以给两个RecyclerView加上android:nestedScrollingEnabled="false",这样RecyclerView自己的滑动会被禁用,整个页面由ScrollView统一控制滚动,避免滑动冲突:

<androidx.recyclerview.widget.RecyclerView
    ...
    android:nestedScrollingEnabled="false" />

内容的提问来源于stack exchange,提问作者BIlly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:33:58