Android 常用容器详解 —— 一篇读懂所有 ViewGroup

面向 Android 初学者,用大白话讲清楚每种容器是什么、什么时候用、有什么区别。


先搞懂:什么叫”容器”?

在 Android 里,容器 = ViewGroup。它本身不显示内容,作用是装其他控件(TextView、Button、ImageView 等),并决定它们怎么排列。

1
2
3
4
5
6
7
8
9
10
View(控件基类)
├── TextView ← 显示文字
├── Button ← 按钮
├── ImageView ← 图片
└── ViewGroup(容器基类)
├── LinearLayout
├── RelativeLayout
├── FrameLayout
├── ConstraintLayout
└── ...

一句话:你写的每一个 XML 布局,顶层一定是一个容器。


1. LinearLayout —— 线性布局

特点

所有子控件排成一行(横向)或一列(纵向),按顺序一个接一个。

核心属性

属性说明
android:orientationhorizontal / vertical横向排列还是纵向排列
android:layout_weight数字按权重分配剩余空间

适用场景

  • 表单页面(纵向排列:标题 → 输入框 → 按钮)
  • 标题栏(横向排列:返回按钮 → 标题 → 右侧图标)
  • 列表项布局

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 纵向排列 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView android:text="用户名" />
<EditText android:hint="请输入" />
<Button android:text="登录" />
</LinearLayout>

<!-- 横向排列,用 weight 均分 -->
<LinearLayout
android:orientation="horizontal">

<Button android:text="取消"
android:layout_width="0dp"
android:layout_weight="1" />

<Button android:text="确定"
android:layout_width="0dp"
android:layout_weight="1" />
</LinearLayout>

⚠️ 注意

  • 嵌套多层 LinearLayout 会导致性能下降(嵌套越深,测量次数越多)
  • 不适合复杂布局

2. RelativeLayout —— 相对布局

特点

子控件相对于父容器或者相对于其他兄弟控件来定位。

核心属性

以父容器为参照:android:layout_alignParentTop, layout_alignParentBottom, layout_alignParentStart, layout_alignParentEnd, layout_centerInParent

以兄弟控件为参照:android:layout_above, layout_below, layout_toStartOf, layout_toEndOf, layout_alignTop, layout_alignBottom

适用场景

  • 元素之间有明确相对关系(A 在 B 右边,C 在 B 下方)
  • 层叠布局(一个控件盖在另一个上面)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 头像贴左上角 -->
<ImageView
android:id="@+id/iv_avatar"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
... />

<!-- 用户名在头像右边 -->
<TextView
android:id="@+id/tv_name"
android:layout_toEndOf="@id/iv_avatar"
android:layout_alignTop="@id/iv_avatar"
android:text="张三" />

<!-- 简介在用户名下方 -->
<TextView
android:id="@+id/tv_bio"
android:layout_below="@id/tv_name"
android:layout_toEndOf="@id/iv_avatar"
android:text="这个人很懒" />
</RelativeLayout>

⚠️ 注意

  • 控件多了容易混乱(互相依赖),调试困难
  • 现代开发中逐渐被 ConstraintLayout 替代

3. FrameLayout —— 帧布局

特点

所有子控件从左上角开始堆叠,后添加的盖在之前的上面。最简单的容器,性能最佳。

核心属性

  • android:layout_gravity:控制子控件在父容器中的位置(center、start、end、top、bottom 等)
  • android:foreground:在前景层加遮罩(常用于点击态)

适用场景

  • 层叠效果(图片上叠文字、头像上叠红点 badge)
  • 占位容器(Fragment 容器、只放一个子控件时)
  • 标题栏居中文字(返回按钮贴左,标题居中,按钮贴右)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- 图片上叠文字 -->
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp">

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="居中文字"
android:textColor="#FFF" />

<!-- 右上角红点 -->
<View
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_gravity="end|top"
android:background="@drawable/bg_red_dot" />
</FrameLayout>

✅ 优点

  • 结构简单,性能好
  • 子控件不会互相影响

4. ConstraintLayout —— 约束布局(⭐ 主力推荐)

特点

通过约束(Constraint)关系定位,灵活度最高。是 Google 官方推荐的首选布局。

核心概念

每个子控件的四条边(上下左右)都需要至少一个约束,否则会在编译时报警告。

1
2
3
4
5
6
7
8
9
10
11
┌──────────────────────────────┐
parent
│ ┌───────┐ │
│ │ AA 的约束: │
│ │ │ 左 → parent
│ └───────┘ 上 → parent
│ ↓ │
│ ┌───────┐ B 的约束: │
│ │ B │ 左 → parent 左 │
│ └───────┘ 上 → A 的下边 │
└──────────────────────────────┘

核心属性(全部以 app: 开头)

属性含义
app:layout_constraintStart_toStartOf左边对齐谁的左边
app:layout_constraintEnd_toEndOf右边对齐谁的右边
app:layout_constraintTop_toTopOf上边对齐谁的上边
app:layout_constraintBottom_toBottomOf下边对齐谁的下边
app:layout_constraintTop_toBottomOf上边贴在谁的下边
app:layout_constraintHorizontal_bias水平偏移比例(0~1,0.5=居中)

适用场景

  • 几乎所有布局——Google 推荐用 ConstraintLayout 替代 LinearLayout + RelativeLayout 嵌套
  • 复杂的扁平化布局(一个 ConstraintLayout 搞定过去要嵌套好几层的事)
  • 响应式布局(不同屏幕尺寸自动适应)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 头像:左上角 -->
<ImageView
android:id="@+id/iv_avatar"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_avatar" />

<!-- 用户名:头像右边,上对齐 -->
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/iv_avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/iv_avatar"
android:text="张三"
android:textSize="18sp"
android:textStyle="bold" />

<!-- 简介:用户名下方 -->
<TextView
android:id="@+id/tv_bio"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/tv_name"
app:layout_constraintEnd_toEndOf="@id/tv_name"
app:layout_constraintTop_toBottomOf="@id/tv_name"
android:text="Android 初学者" />

<!-- 底部按钮:始终贴在父容器底部 -->
<Button
android:id="@+id/btn_submit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="提交" />
</androidx.constraintlayout.widget.ConstraintLayout>

✅ 优点

  • 扁平化:一层搞定复杂布局
  • 性能好:减少嵌套层级
  • 可视化编辑友好(Android Studio 布局编辑器支持拖拽)

⚠️ 注意

  • 需要添加依赖:implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
  • layout_width="0dp" 表示”由约束决定宽度”,非常常用

5. ScrollView / NestedScrollView —— 滚动容器

特点

当内容超过屏幕高度时,提供上下滚动能力。ScrollView 只能放一个直接子控件,NestedScrollView 支持嵌套滑动(配合 RecyclerView 等)。

适用场景

  • 文章详情页
  • 设置页面
  • 表单超过一屏

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<!-- 这里放很多内容,超出屏幕就可以滚动 -->
<TextView android:text="第一段..." />
<TextView android:text="第二段..." />
<ImageView ... />
<TextView android:text="很长很长..." />
</LinearLayout>
</NestedScrollView>

⚠️ 注意

  • ScrollView 只能有一个直接子控件,所以要放多个东西得包一层 LinearLayout 或 ConstraintLayout
  • NestedScrollView 替代 ScrollView,兼容性更好

6. RecyclerView —— 列表容器(进阶)

特点

  • 专门用于大量数据的列表展示,自带复用机制(滑出屏幕的 item 会被回收给新 item 用)
  • 需要配合 Adapter(适配器)使用

适用场景

  • 聊天列表
  • 商品列表
  • 任何”滚动刷不完”的列表

⚠️ 初学者提示

RecyclerView 比上面几个复杂,需要写 Adapter,建议先掌握前五种再学。


📊 横向对比总结

容器排列方式嵌套性能学习难度推荐指数
LinearLayout线性(横/竖)⭐⭐极易⭐⭐⭐
RelativeLayout相对定位⭐⭐中等⭐⭐
FrameLayout层叠⭐⭐⭐极易⭐⭐⭐
ConstraintLayout约束⭐⭐⭐中等⭐⭐⭐⭐⭐
ScrollView滚动极易⭐⭐⭐⭐
RecyclerView列表复用⭐⭐⭐较难⭐⭐⭐⭐⭐

🎯 实际选择指南

1
2
3
4
5
6
7
8
9
我要做的是...

一个简单的纵向排列(表单/菜单) → LinearLayout vertical
一个横向排列(按钮栏/标签) → LinearLayout horizontal
图片上叠文字/红点/水印 → FrameLayout
标题栏(左按钮 + 中间标题 + 右按钮) → FrameLayout 或 ConstraintLayout
复杂页面、需要适配多种屏幕 → ConstraintLayout(首选)
内容超过一屏需要滚动 → NestedScrollView + 内容容器
大量数据的列表(几十上百条) → RecyclerView

黄金法则

能用一层 ConstraintLayout 搞定的,绝不嵌套多层 LinearLayout。

扁平化布局 = 更少的测量次数 = 更流畅的渲染 = 更好的用户体验。


💡 延伸阅读


本文面向 Android 入门开发者,建议配合 Android Studio 实际编写示例来加深理解。动手敲一遍比看十遍管用!