Android 资源体系深度解析 + 四大经典布局实战指南

15 阅读11分钟

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/ 下的子目录有严格命名规范,系统可自动识别用途。以下为必备目录及用途:

image.png

提示:mipmap 只放启动图标;普通图片放 drawable。

三、布局资源:UI 结构的核心载体

布局资源位于 res/layout/,用于声明控件层级与位置规则。Android 布局采用树形结构,渲染时遵循 measure → layout → draw 流程。

本文重点解析四大传统经典布局

  1. LinearLayout(线性布局)
  2. RelativeLayout(相对布局)
  3. TableLayout(表格布局)
  4. FrameLayout(帧布局)

四、LinearLayout 线性布局

image.png

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"

image.png

    android:layout_width="match_parent"    
    android:layout_height="match_parent"  
    android:orientation="horizontal">  

2️⃣ android:layout_width="0dp",不自己固定宽度,交给权重来决定。当使用 layout_weight 时,通常把 layout_width 设为 0dp,如果设置了固定宽度,权重是在 剩余空间上分配(容易混乱)

image.png

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. 运行效果

image.png

LinearLayout 的核心效果是按方向线性排列 + 权重比例分配空间。它解决了固定尺寸无法适配不同屏幕的问题,通过 weight 机制实现了灵活的响应式布局,是构建简单到中等复杂度界面的首选布局方案。

五、RelativeLayout 相对布局

1. 核心原理

RelativeLayout是一种视图容器,子控件可参照同级控件或父容器进行定位,它能减少布局嵌套、让层级更扁平,进而提升界面性能,适合用来替换多层嵌套的线性布局。

image.png

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的每个控件可以 相对于父容器 定位(靠边或居中),也可以 相对于其他控件 定位

image.png

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 - 底部对齐

image.png

按钮2 - 水平居中

image.png

按钮3 - 相对定位

image.png

4. 运行效果

image.png

六、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.运行效果

image.png

第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"

常用取值:

image.png

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" />

最终呈现的效果:

image.png 只能看到最上面的 深蓝色小按钮(20dp),其他按钮都被盖住了,只能看到最外面一圈颜色边界。

八、四大布局对比与选型建议

布局优点缺点推荐场景
LinearLayout简单易写、权重好用嵌套多性能下降通用排列、按钮组
RelativeLayout灵活、少嵌套属性复杂、双次测量中等复杂 UI、详情页
TableLayout自动对齐、结构强灵活性低表单、设置页
FrameLayout最轻量、性能最高仅支持叠加容器、角标、弹窗

Android 资源体系是规范化开发的基础,合理分类可大幅提升维护效率与适配能力。四大传统布局各有侧重,掌握其原理与边界,才能写出层级少、性能高、易扩展的优质 UI 代码。