惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
P
Privacy International News Feed
S
Schneier on Security
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
aimingoo的专栏
aimingoo的专栏
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
Help Net Security
Help Net Security
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Archives - TechRepublic
Security Archives - TechRepublic
云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
雷峰网
雷峰网
博客园 - 司徒正美
V
V2EX
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
N
News | PayPal Newsroom
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
Google DeepMind News
Google DeepMind News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
U
Unit 42
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
博客园 - Franky
I
InfoQ
D
DataBreaches.Net
爱范儿
爱范儿
Y
Y Combinator Blog
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

博客园 - y丶innocence

临时111 Android Kotlin OkHttp3 WebSocket 长连接与 Gson 数据解析系统笔记 Android + Kotlin + OkHttp WebSocket 相关概念与使用流程笔记(TLS/证书 + 鉴权/会话) AI对话导出markdown格式流程 代理转发 分享文件 面向全球的app的excel导出和kotlin IO原理 安卓导出笔记(未整理) java&kotlin listener 0.7 动画 0.4 View 工作流程 0.3 view 滑动冲突 13. Jetpack 0. 安卓开发艺术探索参考资料 12. Material Design 7. 持久化技术 5. Fragment java 基础 4. UI 开发 3. Activity 2.2 Kotlin 面向对象 2.3 Kotlin高级 2.1 Kotlin基础 1. Android简介 [OpenJudge] 反正切函数的应用 (枚举)(数学) [OpenJudge] 摘花生 (模拟)
RecyclerView 数据多时无法滑动:ConstraintLayout 约束高度修复笔记
y丶innocence · 2026-05-15 · via 博客园 - y丶innocence

RecyclerView 数据多时无法滑动:ConstraintLayout 约束高度修复笔记

1. 修改背景

  • 现象:RecyclerView 数据较多时无法正常滑动
  • 原因:列表区域被测量为“无限高度”,RecyclerView 把所有 item 总高度一次性撑开,未形成可滚动的有限窗口
  • 目标:通过约束父容器高度,让 RecyclerView 获得有限的滚动窗口,从而触发内部滚动

2. 初始代码(问题示例)

常见错误结构:外层容器高度未被上下约束限制,内部 RecyclerView 使用 wrap_content,导致内容无限撑高

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.cardview.widget.CardView
        android:id="@+id/cardContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

问题点总结:

  • 只有 top 约束,没有 bottom 约束,最大高度边界不明确
  • 外层 CardView 为 wrap_content,完全由子 View 决定高度
  • RecyclerView 为 wrap_content,会测量所有 item 总高度,自身不认为需要滚动,滚动条件被破坏

3. 修复目标与核心思路

  • 父容器必须提供“有限高度窗口”(上下边界明确)
  • wrap_content 必须服从约束,禁止被内容无限撑开
  • RecyclerView 自身应占据父容器的可视高度(match_parent),内容超出时在内部滚动

4. 修改项 1:增加 bottom 约束

4.1 增加属性

  • app:layout_constraintBottom_toBottomOf="parent"

4.2 含义

  • 将 View 底部约束到父布局底部
  • 与 top 约束配合形成上下高度边界
  • 为 View 提供最大可用高度参考

4.3 不增加的问题

  • 只有 top 约束,无法确定最大高度
  • wrap_content 完全由子 View 决定高度
  • RecyclerView 内容多时会无限撑高父容器

4.4 增加后的作用

  • 明确 View 不能无限向下增长(具备边界前提)
  • 但如果仍是 wrap_content,仍可能被内容撑开(需要 constrainedHeight 配合)

5. 修改项 2:增加 constrainedHeight(核心)

5.1 增加属性

  • app:layout_constrainedHeight="true"

5.2 含义(关键点)

  • 控制 wrap_content 是否必须服从约束
  • 默认情况下 wrap_content 可能突破约束继续变大
  • 设置 true 后,高度必须受上下约束限制

5.3 不增加的问题

  • 即使有 bottom 约束,wrap_content 仍会被内容撑开
  • RecyclerView 会测量所有 item 的总高度
  • bottom 约束实际无法生效

5.4 增加后的作用

  • 内容少:仍能表现为 wrap_content 的自然高度
  • 内容多:高度被限制在 top/bottom 约束范围内
  • 真正阻止父容器无限长高(核心修改)

6. 修改项 3:RecyclerView 高度改为 match_parent

6.1 修改前(wrap_content)

  • RecyclerView 高度等于所有 item 总高度
  • RecyclerView 不认为自己需要滚动
  • 滚动条件被破坏

6.2 修改后(match_parent)

  • RecyclerView 高度等于父 CardView 高度
  • 父 CardView 高度已被约束(有限窗口)
  • 内容高度大于自身高度,触发 RecyclerView 内部滚动

6.3 修改结论

  • 给 RecyclerView 一个有限的可视区域
  • 明确滚动主体是 RecyclerView
  • 列表滑动得以成立

7. 修改项 4:增加 vertical_bias=0(仅调整位置)

7.1 增加属性

  • app:layout_constraintVertical_bias="0"

7.2 含义

  • 当 View 同时有 top/bottom 约束,且自身高度小于可用空间
  • bias 决定 View 在上下约束中的位置

7.3 不设置的问题

  • 默认 bias=0.5,内容较少时 View 会垂直居中
  • UI 视觉上会下移,影响一致性

7.4 设置后的作用

  • View 紧贴 top 约束,保持原布局结构
  • 不影响滚动,仅影响位置

8. 修改后代码(修复示例:可滚动窗口形成)

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.cardview.widget.CardView
        android:id="@+id/cardContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constrainedHeight="true"
        app:layout_constraintVertical_bias="0">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

9. 修改生效的整体逻辑(组合拳)

  • 单点修改不足:
    • 仅加 bottom 约束:wrap_content 仍可能撑开
    • 仅加 constrainedHeight:缺少最大高度边界
    • RecyclerView 不改为 match_parent:仍测量总高度,不触发滚动
  • 组合修改后的完整链路:
    1. bottom 约束提供最大高度边界
    2. constrainedHeight 强制 wrap_content 服从边界
    3. RecyclerView match_parent 填满受限高度
    4. 内容高度大于自身高度,RecyclerView 内部滚动成立

10. 修改总结

  • RecyclerView 能否滚动,取决于父布局是否提供有限高度
  • 本次修改的本质是限制父容器高度
  • 将布局从“无限高度内容容器”转变为“受约束的滚动窗口”