Android 开发核心:资源管理与布局优化
面对 各类手机屏幕尺寸、分辨率不一的情况,若手动控制控件位置与大小,开发会极为繁琐,Android 因此提供了布局管理器来自动适配界面。布局文件会在加载时被解析并实例化为对应 View 对象,构成 UI 层级并伴随组件生命周期,进而影响应用内存分配。本文从资源分类、目录规范到四大经典布局深度拆解,覆盖原理、属性、实战与选型思路。
开发环境:Android Studio Hedgehog | 2023.1.1
适配版本:Android 5.0 ~ Android 14
一、Android 资源目录结构
res/
├── drawable/ # 图片、形状、选择器等
├── drawable-hdpi/ # 不同密度图片
├── layout/ # 布局文件
├── values/
│ ├── strings.xml # 字符串
│ ├── colors.xml # 颜色
│ ├── dimens.xml # 尺寸
│ ├── styles.xml # 样式/主题
│ └── arrays.xml # 数组
├── mipmap/ # 应用图标
├── anim/ # 补间动画
├── animator/ # 属性动画
├── menu/ # 菜单
└── raw/ # 原始文件(音频、视频等)
资源是应用中独立于 Java/Kotlin 代码的静态文件,统一存放于 res/ 目录。系统会在编译时为其生成 R 类索引,支持代码与 XML 双向引用。
二、Android 资源目录全分类
res/ 下的子目录有严格命名规范,系统可自动识别用途。以下为必备目录及用途:
提示:mipmap 只放启动图标;普通图片放 drawable。
三、布局资源:UI 结构的核心载体
布局资源位于 res/layout/,用于声明控件层级与位置规则。Android 布局采用树形结构,渲染时遵循 measure → layout → draw 流程。
本文重点解析四大传统经典布局:
- LinearLayout(线性布局)
- RelativeLayout(相对布局)
- TableLayout(表格布局)
- FrameLayout(帧布局)
四、LinearLayout 线性布局
1. 核心原理
LinearLayout作为一种视图容器,只能沿水平或垂直单一方向排列子控件,会按照添加顺序逐个摆放控件;垂直方向时每次只放一个控件且独占一行,水平方向时所有控件只占一行,高度以最高子控件为准,同时它还会处理控件间距与左右居中这类对齐方式,LinearLayout是 Android 最基础、使用最广泛的布局。
2. 实战代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮2"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="按钮3"/>
</LinearLayout>
3.核心方法
LinearLayout的所有控件 排成一排或者 排成一列,通过 orientation 控制排列方向,通过 layout_weight 控制 空间分配比例
1️⃣ android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
2️⃣ android:layout_width="0dp",不自己固定宽度,交给权重来决定。当使用 layout_weight 时,通常把 layout_width 设为 0dp,如果设置了固定宽度,权重是在 剩余空间上分配(容易混乱)
3️⃣ android:layout_weight="数字",数字越大,占的空间比例越大。所有控件的 weight 值加起来作为分母,每个控件的 weight 作为分子
控件宽度 = 父容器总宽度 × (自己的weight / 所有weight之和)
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按钮2"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="按钮3"/>
按钮1宽度 = 400 × (1/4) = 100dp
按钮2宽度 = 400 × (1/4) = 100dp
按钮3宽度 = 400 × (2/4) = 200dp
4. 运行效果
LinearLayout 的核心效果是按方向线性排列 + 权重比例分配空间。它解决了固定尺寸无法适配不同屏幕的问题,通过 weight 机制实现了灵活的响应式布局,是构建简单到中等复杂度界面的首选布局方案。
五、RelativeLayout 相对布局
1. 核心原理
RelativeLayout是一种视图容器,子控件可参照同级控件或父容器进行定位,它能减少布局嵌套、让层级更扁平,进而提升界面性能,适合用来替换多层嵌套的线性布局。
2. 实战代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/AppTheme"
android:id="@+id/mainRelativelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dp"
>
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"/>
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
android:layout_centerHorizontal="true"
android:layout_marginTop="260dp"/>
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/btn_two"
android:layout_marginLeft="-5dp"
android:layout_marginBottom="151dp"
android:layout_toRightOf="@id/btn_two"
android:text="按钮3" />
</RelativeLayout>
3.核心方法
RelativeLayout的每个控件可以 相对于父容器 定位(靠边或居中),也可以 相对于其他控件 定位
1️⃣ 相对于父容器定位
android:layout_alignParentBottom="true",让控件紧贴父容器底部
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp",“离底部20dp”,在底部留出空白
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"/> <!-- (这里) -->
android:layout_centerHorizontal="true",水平方向站在中间,让控件在屏幕水平居中
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
android:layout_centerHorizontal="true" <!-- (这里) -->
android:layout_marginTop="260dp"/>
android:layout_marginTop="260dp",“从顶部往下260dp”,设置距离顶部的距离
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
android:layout_centerHorizontal="true"
android:layout_marginTop="260dp"/> <!-- (这里) -->
2️⃣ 相对于其他控件定位
android:layout_toRightOf="@id/btn_two",让控件位于另一个控件的右侧,“放在按钮2的右手边”
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/btn_two"
android:layout_marginLeft="-5dp"
android:layout_marginBottom="151dp"
android:layout_toRightOf="@id/btn_two" <!-- (这里) -->
android:text="按钮3" />
android:layout_alignBottom="@id/btn_two",让两个控件的底部在同一水平线上
android:layout_alignBottom="@id/btn_two"
android:layout_marginLeft="-5dp",负值表示向左偏移,让控件重叠一部分,这里向坐重叠了5dp
android:layout_marginLeft="-5dp"
android:layout_marginBottom="151dp",在已对齐的基础上再调整,底部向上提151dp
android:layout_marginBottom="151dp"
RelativeLayout = 关系网定位 + 可负值微调
按钮1 - 底部对齐
按钮2 - 水平居中
按钮3 - 相对定位
4. 运行效果
六、TableLayout 表格布局
1. 核心原理
TableLayout继承自LinearLayout,本质是线性布局,以行列形式管理UI组件,其行数和列数由TableRow与其他组件决定:添加一个TableRow即为一行,TableRow内每加一个子组件就新增一列;若直接向TableLayout添加组件,该组件会独占一行。列宽由该列最宽单元格决定,布局宽度默认占满父容器。它支持单元格三种行为方式:Collapsed(列隐藏)、Shrinkable(列可收缩以适配父容器)、Stretchable(列可拉伸填满空余空间),同时可使用LinearLayout的XML属性,还拥有自身专属XML属性。
2. 实战代码
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="2" >
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="按钮1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:text="按钮2" />
</TableRow>
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:text="按钮3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:text="按钮4" />
</TableRow>
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:text="按钮5" />
</TableRow>
</TableLayout>
3. 核心方法
TableLayout类似于 Excel 表格 或者 HTML 里的 <table> ,把界面按行和列来组织,每个控件占据一个单元格。
1️⃣ android:stretchColumns="2",列号从 0 开始计数, stretchColumns="2" 表示第 2 列(也就是第三列)会被拉伸,如果有多列,用逗号分隔,如 stretchColumns="0,2"
就是说当表格总宽度小于屏幕宽度时,第2列会自动变宽,把剩余空间填满。
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="2"
2️⃣ TableRow:每一对 <TableRow> 标签就是 表格的一行, TableLayout 里面可以放多个 TableRow,而每个 TableRow 里面的控件,自动成为 这一行的列
<TableRow>
<Button android:layout_column="2" android:text="按钮5" />
</TableRow>
3️⃣ android:layout_column="数字",控件级别的属性,列号从 0 开始排序,不写的话,默认按顺序自动排列(第一个控件在第0列,第二个在第1列...),写了的话,可以跳过某些列或者指定位置
<TableRow>
<Button android:layout_column="0" android:text="按钮1" />
<Button android:layout_column="1" android:text="按钮2" />
</TableRow>
4.运行效果
第0列和第1列宽度是 wrap_content(按内容自适应),第2列被拉伸,占据了所有剩余宽度,我们可以通过 layout_column 可以灵活控制按钮放在哪一列
TableLayout = 表格容器 + stretchColumns(列拉伸)+ TableRow(行)+ layout_column(列定位)
七、FrameLayout 帧布局
1. 核心原理
FrameLayout采用栈式堆叠方式放置控件,后添加的控件会显示在最上层;它会为每个子控件创建一帧空白区域,各子控件独占一帧,并依据gravity属性自动对齐。
2. 关键代码
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_one"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:background="#ff0000" />
<Button
android:id="@+id/btn_two"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_gravity="center"
android:background="#00ff00" />
<Button
android:id="@+id/btn_three"
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_gravity="center"
android:background="#0000ff" />
<Button
android:id="@+id/btn_four"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:background="#ff1243" />
<Button
android:id="@+id/btn_five"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:background="#324678" />
</FrameLayout>
3. 核心方法
FrameLayout有点类似于俄罗斯方块,所有控件都 从左上角开始堆叠,后添加的控件 盖住 先添加的控件,默认所有控件都贴在 左上角
1️⃣ android:layout_gravity="center"
layout_gravity 决定了控件在 FrameLayout 中的 对齐方式
center表示 水平居中 + 垂直居中- 如果不设置,默认是
top|left(左上角)
android:layout_gravity="center"
常用取值:
2️⃣ 控件大小设置
android:layout_width="300dp"
android:layout_height="300dp"
每个按钮的 宽高 依次递减
- 按钮1:300dp × 300dp(最大,在最底层)
- 按钮2:220dp × 220dp
- 按钮3:140dp × 140dp
- 按钮4:80dp × 80dp
- 按钮5:20dp × 20dp(最小,在最顶层)
FrameLayout 不关心控件之间的位置关系,只关心 每个控件相对于自己的位置,所有控件都 独立定位,互不影响,比较适合 单控件全屏显示 或者 重叠效果。
下面是根据上面的代码分析的内容:
第1层(最底层):按钮1(红色):300×300dp
<Button android:layout_width="300dp" android:layout_height="300dp"
android:layout_gravity="center" android:background="#ff0000" />
第2层:按钮2(绿色):220×220dp
<Button android:layout_width="220dp" android:layout_height="220dp"
android:layout_gravity="center" android:background="#00ff00" />
第3层:按钮3(蓝色):140×140dp
<Button android:layout_width="140dp" android:layout_height="140dp"
android:layout_gravity="center" android:background="#0000ff" />
第4层:按钮4(粉红色):80×80dp
<Button android:layout_width="80dp" android:layout_height="80dp"
android:layout_gravity="center" android:background="#ff1243" />
第5层(最顶层):按钮5(深蓝色):20×20dp
<Button android:layout_width="20dp" android:layout_height="20dp"
android:layout_gravity="center" android:background="#324678" />
最终呈现的效果:
只能看到最上面的 深蓝色小按钮(20dp),其他按钮都被盖住了,只能看到最外面一圈颜色边界。
八、四大布局对比与选型建议
| 布局 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| LinearLayout | 简单易写、权重好用 | 嵌套多性能下降 | 通用排列、按钮组 |
| RelativeLayout | 灵活、少嵌套 | 属性复杂、双次测量 | 中等复杂 UI、详情页 |
| TableLayout | 自动对齐、结构强 | 灵活性低 | 表单、设置页 |
| FrameLayout | 最轻量、性能最高 | 仅支持叠加 | 容器、角标、弹窗 |
Android 资源体系是规范化开发的基础,合理分类可大幅提升维护效率与适配能力。四大传统布局各有侧重,掌握其原理与边界,才能写出层级少、性能高、易扩展的优质 UI 代码。