Android入门教程 - 第三章:Android布局全攻略

🎨 Android入门教程 - 第三章:Android布局全攻略

💡 前言:学习Android开发,布局是绕不开的第一关。本章将带你系统掌握Android六大布局,从最简单的线性排列到复杂的网格设计,让你的App界面专业又美观!


📚 本章学习路线图

布局基础概念 LinearLayout 线性布局 RelativeLayout 相对布局 FrameLayout 帧布局 TableLayout 表格布局 GridLayout 网格布局 综合实战

学完本章你将掌握:

  • ✅ 6种Android基本布局的使用方法
  • ✅ 每种布局的特点和最佳应用场景
  • ✅ 布局嵌套技巧实现复杂界面
  • ✅ 界面适配不同屏幕的方法

🎯 一、布局是什么?为什么要学布局?

1.1 布局的本质

布局(Layout) 是Android中的容器控件,就像是一个"组织者",负责管理和安排其他控件(按钮、文本框等)在屏幕上的位置和大小。

1.2 生动的类比

想象你在装修房子:

概念 类比 说明
布局 房间的格局设计 决定家具放在哪里
控件 各种家具 沙发、桌子、椅子等
屏幕 整个房子 所有内容的承载空间

再比如:

  • 📚 布局像书架的隔板:决定书籍如何摆放
  • 🎯 布局像停车场的车位:规划每辆车的位置
  • 🎨 布局像画布的构图:安排画面元素的位置

1.3 Android六大布局家族

序号 布局名称 核心特点 典型应用
1️⃣ LinearLayout 线性排列(横向/纵向) 按钮组、列表项
2️⃣ RelativeLayout 相对定位 复杂界面、表单
3️⃣ FrameLayout 层叠显示 轮播图、遮罩层
4️⃣ TableLayout 表格结构 数据表格、日历
5️⃣ GridLayout 网格布局 计算器、相册
6️⃣ AbsoluteLayout 绝对定位(已废弃) ⚠️ 不推荐使用

📐 二、LinearLayout - 最常用的线性布局

2.1 LinearLayout是什么?

LinearLayout(线性布局) 将子控件按照垂直 或水平方向依次排列,就像排队一样简单明了。

2.2 生活中的LinearLayout

复制代码
垂直排列 (vertical)          水平排列 (horizontal)
    
    📱                      📱 📱 📱 📱
    📱                      ← 水平排列 →
    📱                   
    📱                   
    ↓                    
  垂直排列                
  • 排队买票:人们一个接一个排成一列 → 垂直LinearLayout
  • 并排停车:车辆横向依次排列 → 水平LinearLayout

2.3 核心属性速查表

属性名 作用 可选值 示例代码
orientation 排列方向 vertical(垂直) horizontal(水平) android:orientation="vertical"
layout_weight 权重分配 数字(如1, 2, 3) android:layout_weight="1"
gravity 子控件对齐方式 center, left, right, top, bottom android:gravity="center"
layout_gravity 自身在父容器中的对齐 同上 android:layout_gravity="center"

2.4 实战案例:垂直排列的登录界面

xml 复制代码
<?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="vertical"
    android:padding="24dp"
    android:background="#F5F5F5">

    <!-- 标题 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎登录"
        android:textSize="28sp"
        android:textColor="#333333"
        android:textStyle="bold"
        android:layout_gravity="center"
        android:layout_marginBottom="32dp"/>

    <!-- 用户名输入框 -->
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        android:padding="12dp"
        android:background="@android:color/white"
        android:layout_marginBottom="16dp"/>

    <!-- 密码输入框 -->
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码"
        android:inputType="textPassword"
        android:padding="12dp"
        android:background="@android:color/white"
        android:layout_marginBottom="24dp"/>

    <!-- 登录按钮 -->
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"
        android:textSize="18sp"
        android:padding="12dp"
        android:background="#4CAF50"
        android:textColor="@android:color/white"/>

</LinearLayout>

效果预览:

复制代码
┌─────────────────────────┐
│                         │
│       欢迎登录          │
│                         │
│  ┌──────────────────┐  │
│  │ 请输入用户名      │  │
│  └──────────────────┘  │
│                         │
│  ┌──────────────────┐  │
│  │ 请输入密码 ••••   │  │
│  └──────────────────┘  │
│                         │
│  ┌──────────────────┐  │
│  │      登录         │  │
│  └──────────────────┘  │
│                         │
└─────────────────────────┘

2.5 权重(Weight)详解:最重要的属性!

权重是LinearLayout的灵魂,它决定了控件如何分配剩余空间。

权重计算公式
java 复制代码
实际大小 = 原始大小 + (剩余空间 × 权重比例)
实战案例:三个按钮平分空间
xml 复制代码
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    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="1"
        android:text="按钮3"/>

</LinearLayout>

关键点:

  1. layout_width="0dp":让权重生效
  2. layout_weight="1":三个按钮权重相同,平分空间
不同权重的效果对比
xml 复制代码
<!-- 权重比例 1:2:1 -->
<Button android:layout_weight="1" android:text="小"/>
<Button android:layout_weight="2" android:text="大"/>
<Button android:layout_weight="1" android:text="小"/>

视觉效果:

复制代码
┌────┬──────────┬────┐
│ 小 │    大    │ 小 │
└────┴──────────┴────┘
 25%      50%     25%

2.6 Java代码动态创建LinearLayout

java 复制代码
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 创建垂直LinearLayout
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(20, 20, 20, 20);
        
        // 创建TextView
        TextView textView = new TextView(this);
        textView.setText("动态创建的文本");
        textView.setTextSize(18);
        
        // 创建Button
        Button button = new Button(this);
        button.setText("动态按钮");
        
        // 添加到布局
        layout.addView(textView);
        layout.addView(button);
        
        // 设置为Activity的内容视图
        setContentView(layout);
    }
}

2.7 LinearLayout常见问题

问题 原因 解决方案
控件显示不全 宽高设置不当 使用wrap_content或match_parent
权重不生效 宽度不是0dp 设置layout_width="0dp"
控件重叠 方向设置错误 检查orientation属性

🔗 三、RelativeLayout - 灵活的相对布局

3.1 RelativeLayout是什么?

RelativeLayout(相对布局) 通过相对位置关系 来排列控件。每个控件可以相对于父容器 或其他控件定位。

3.2 生活中的RelativeLayout

像玩拼图:

  • "把沙发放在电视对面" → 相对于电视定位
  • "把茶几放在沙发前面" → 相对于沙发定位
  • "把台灯放在房间中央" → 相对于父容器定位

3.3 RelativeLayout核心属性分类

📍 相对于父容器的定位
属性 作用 视觉效果
layout_alignParentTop 顶部对齐 控件贴着屏幕上边缘
layout_alignParentBottom 底部对齐 控件贴着屏幕下边缘
layout_alignParentLeft 左对齐 控件贴着屏幕左边缘
layout_alignParentRight 右对齐 控件贴着屏幕右边缘
layout_centerInParent 居中 控件在屏幕正中央
layout_centerHorizontal 水平居中 控件水平方向居中
layout_centerVertical 垂直居中 控件垂直方向居中
📍 相对于其他控件的定位
属性 作用 使用示例
layout_above 在指定控件上方 android:layout_above="@id/centerView"
layout_below 在指定控件下方 android:layout_below="@id/centerView"
layout_toLeftOf 在指定控件左边 android:layout_toLeftOf="@id/centerView"
layout_toRightOf 在指定控件右边 android:layout_toRightOf="@id/centerView"
📍 对齐其他控件的边缘
属性 作用
layout_alignTop 顶部与指定控件对齐
layout_alignBottom 底部与指定控件对齐
layout_alignLeft 左边与指定控件对齐
layout_alignRight 右边与指定控件对齐

3.4 实战案例:十字星布局

xml 复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <!-- 中心控件 -->
    <TextView
        android:id="@+id/centerView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="中心"
        android:gravity="center"
        android:background="#2196F3"
        android:textColor="@android:color/white"
        android:layout_centerInParent="true"/>

    <!-- 上方控件 -->
    <TextView
        android:id="@+id/topView"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:text="上"
        android:gravity="center"
        android:background="#4CAF50"
        android:textColor="@android:color/white"
        android:layout_above="@id/centerView"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp"/>

    <!-- 下方控件 -->
    <TextView
        android:id="@+id/bottomView"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:text="下"
        android:gravity="center"
        android:background="#FF5722"
        android:textColor="@android:color/white"
        android:layout_below="@id/centerView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"/>

    <!-- 左边控件 -->
    <TextView
        android:id="@+id/leftView"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:text="左"
        android:gravity="center"
        android:background="#FFC107"
        android:textColor="@android:color/white"
        android:layout_toLeftOf="@id/centerView"
        android:layout_centerVertical="true"
        android:layout_marginEnd="20dp"/>

    <!-- 右边控件 -->
    <TextView
        android:id="@+id/rightView"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:text="右"
        android:gravity="center"
        android:background="#9C27B0"
        android:textColor="@android:color/white"
        android:layout_toRightOf="@id/centerView"
        android:layout_centerVertical="true"
        android:layout_marginStart="20dp"/>

</RelativeLayout>

效果预览:

复制代码
        ┌────┐
        │ 上 │
        └────┘
          ↑
   ┌────┐ ┌────────┐ ┌────┐
   │ 左 │←│  中心  │→│ 右 │
   └────┘ └────────┘ └────┘
          ↓
        ┌────┐
        │ 下 │
        └────┘

3.5 实战案例:微信聊天界面布局

xml 复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 顶部标题栏 -->
    <LinearLayout
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="#1AAD19"
        android:layout_alignParentTop="true"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="聊天"
            android:textSize="20sp"
            android:textColor="@android:color/white"/>

    </LinearLayout>

    <!-- 底部输入栏 -->
    <LinearLayout
        android:id="@+id/inputBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:padding="8dp"
        android:background="#F5F5F5">

        <EditText
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入消息"
            android:padding="8dp"
            android:background="@android:color/white"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送"
            android:layout_marginStart="8dp"/>

    </LinearLayout>

    <!-- 中间消息列表区域 -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/titleBar"
        android:layout_above="@id/inputBar"
        android:background="@android:color/white">

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="这里显示聊天消息"
                android:textSize="16sp"/>

        </LinearLayout>

    </ScrollView>

</RelativeLayout>

3.6 RelativeLayout vs LinearLayout 对比

对比项 LinearLayout RelativeLayout
布局方式 线性排列 相对定位
嵌套层数 可能需要多层嵌套 通常一层即可
性能 较好 略差(测量过程复杂)
灵活性 较低 非常高
适用场景 简单列表、按钮组 复杂界面、表单
学习难度 ⭐⭐ ⭐⭐⭐

3.7 RelativeLayout使用技巧

✅ 推荐做法:

  1. 先定位关键的"锚点"控件(如中心控件)
  2. 其他控件相对于锚点定位
  3. 使用ID引用时确保ID已定义在前面

❌ 常见错误:

xml 复制代码
<!-- 错误:centerView还未定义就被引用 -->
<TextView
    android:layout_below="@id/centerView"/>  <!-- centerView在下面才定义 -->

<TextView
    android:id="@+id/centerView"/>

✅ 正确做法:

xml 复制代码
<!-- 正确:先定义centerView -->
<TextView
    android:id="@+id/centerView"/>

<TextView
    android:layout_below="@id/centerView"/>

🎬 四、FrameLayout - 堆叠式帧布局

4.1 FrameLayout是什么?

FrameLayout(帧布局) 将所有子控件叠加显示,就像一叠扑克牌,后添加的控件会覆盖在前面的控件上方。

4.2 生活中的FrameLayout

场景 说明
🃏 叠扑克牌 一张张叠在一起,最上面的牌可见
🖼️ 相框 可以在同一位置放多张照片
🎭 舞台布景 背景、中景、前景层层叠加

4.3 FrameLayout核心属性

属性 作用 可选值
layout_gravity 控件在帧布局中的位置 center, top, bottom, left, right
foreground 前景图片/颜色 资源ID或颜色值
foregroundGravity 前景对齐方式 同layout_gravity

4.4 实战案例:图片加载遮罩层

xml 复制代码
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 第一层:背景图片 -->
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/background"
        android:scaleType="centerCrop"/>

    <!-- 第二层:半透明遮罩 -->
    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#80000000"/>  <!-- 50%透明的黑色 -->

    <!-- 第三层:加载动画(居中显示) -->
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>

    <!-- 第四层:提示文字 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载中..."
        android:textColor="@android:color/white"
        android:textSize="16sp"
        android:layout_gravity="center"
        android:layout_marginTop="80dp"/>

</FrameLayout>

分层示意图:

复制代码
┌─────────────────────────┐
│                         │  ← 第4层:提示文字
│       加载中...         │
│          ⭕             │  ← 第3层:加载动画
│    (半透明黑色遮罩)      │  ← 第2层:遮罩
│    [背景图片]           │  ← 第1层:背景
└─────────────────────────┘

4.5 实战案例:轮播图指示器

xml 复制代码
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <!-- 轮播图ViewPager -->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!-- 底部指示器(在ViewPager上层) -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:layout_marginBottom="16dp"
        android:orientation="horizontal">

        <View
            android:layout_width="8dp"
            android:layout_height="8dp"
            android:background="@drawable/dot_selected"
            android:layout_margin="4dp"/>

        <View
            android:layout_width="8dp"
            android:layout_height="8dp"
            android:background="@drawable/dot_normal"
            android:layout_margin="4dp"/>

        <View
            android:layout_width="8dp"
            android:layout_height="8dp"
            android:background="@drawable/dot_normal"
            android:layout_margin="4dp"/>

    </LinearLayout>

</FrameLayout>

4.6 FrameLayout的layout_gravity组合用法

xml 复制代码
<!-- 九宫格位置演示 -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 左上角 -->
    <Button
        android:layout_gravity="top|left"
        android:text="左上"/>

    <!-- 正上方 -->
    <Button
        android:layout_gravity="top|center_horizontal"
        android:text="上"/>

    <!-- 右上角 -->
    <Button
        android:layout_gravity="top|right"
        android:text="右上"/>

    <!-- 正中间 -->
    <Button
        android:layout_gravity="center"
        android:text="中"/>

    <!-- 左下角 -->
    <Button
        android:layout_gravity="bottom|left"
        android:text="左下"/>

    <!-- 正下方 -->
    <Button
        android:layout_gravity="bottom|center_horizontal"
        android:text="下"/>

    <!-- 右下角 -->
    <Button
        android:layout_gravity="bottom|right"
        android:text="右下"/>

</FrameLayout>

效果示意:

复制代码
┌─────────────────────────┐
│ 左上   上      右上      │
│                         │
│ 左     中       右       │
│                         │
│ 左下   下      右下      │
└─────────────────────────┘

4.7 FrameLayout典型应用场景

应用场景 说明 层级结构
🎠 轮播图 ViewPager + 指示器 图片层 → 指示器层
💬 对话框 内容 + 遮罩背景 遮罩层 → 内容层
🔄 加载动画 内容 + 加载提示 内容层 → 加载层
🎮 游戏界面 背景 + 角色 + UI 多层叠加
📹 视频播放 视频 + 控制条 视频层 → 控制层

4.8 Java代码动态添加层

java 复制代码
public class FrameLayoutDemo extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        FrameLayout frameLayout = new FrameLayout(this);
        
        // 添加背景层
        ImageView bgImage = new ImageView(this);
        bgImage.setImageResource(R.drawable.background);
        bgImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
        frameLayout.addView(bgImage);
        
        // 添加遮罩层
        View mask = new View(this);
        mask.setBackgroundColor(0x80000000);  // 半透明黑色
        frameLayout.addView(mask);
        
        // 添加前景内容
        TextView text = new TextView(this);
        text.setText("前景文字");
        text.setTextColor(Color.WHITE);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT,
            Gravity.CENTER
        );
        text.setLayoutParams(params);
        frameLayout.addView(text);
        
        setContentView(frameLayout);
    }
}

📊 五、TableLayout - 表格式布局

5.1 TableLayout是什么?

TableLayout(表格布局) 以行和列的形式组织控件,就像Excel表格一样规整。

5.2 生活中的TableLayout

场景 特点
📊 Excel表格 行列清晰,数据规整
📅 课程表 时间、科目按表格排列
🎯 成绩单 姓名、科目、分数列表

5.3 TableLayout核心概念

xml 复制代码
<TableLayout>              ← 表格容器
    <TableRow>             ← 一行
        <TextView/>        ← 第1列
        <TextView/>        ← 第2列
        <TextView/>        ← 第3列
    </TableRow>
    <TableRow>             ← 下一行
        <TextView/>
        <TextView/>
        <TextView/>
    </TableRow>
</TableLayout>

5.4 TableLayout核心属性

属性 作用 使用示例
stretchColumns 指定可拉伸的列 android:stretchColumns="*"(所有列) android:stretchColumns="0,2"(第0列和第2列)
shrinkColumns 指定可收缩的列 android:shrinkColumns="1"
collapseColumns 指定可隐藏的列 android:collapseColumns="2"
layout_span 跨列显示 android:layout_span="3"(跨3列)
layout_column 指定列位置 android:layout_column="1"(放在第1列)

5.5 实战案例:学生成绩表

xml 复制代码
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stretchColumns="*"
    android:padding="16dp"
    android:background="#F5F5F5">

    <!-- 标题行 -->
    <TableRow
        android:background="#2196F3"
        android:padding="12dp">

        <TextView
            android:text="姓名"
            android:textColor="@android:color/white"
            android:textSize="16sp"
            android:textStyle="bold"
            android:gravity="center"/>

        <TextView
            android:text="语文"
            android:textColor="@android:color/white"
            android:textSize="16sp"
            android:textStyle="bold"
            android:gravity="center"/>

        <TextView
            android:text="数学"
            android:textColor="@android:color/white"
            android:textSize="16sp"
            android:textStyle="bold"
            android:gravity="center"/>

        <TextView
            android:text="英语"
            android:textColor="@android:color/white"
            android:textSize="16sp"
            android:textStyle="bold"
            android:gravity="center"/>

    </TableRow>

    <!-- 分隔线 -->
    <View
        android:layout_height="1dp"
        android:background="#CCCCCC"/>

    <!-- 数据行1 -->
    <TableRow
        android:background="@android:color/white"
        android:padding="10dp">

        <TextView
            android:text="张三"
            android:textSize="14sp"
            android:gravity="center"/>

        <TextView
            android:text="95"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

        <TextView
            android:text="88"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

        <TextView
            android:text="92"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

    </TableRow>

    <!-- 分隔线 -->
    <View
        android:layout_height="1dp"
        android:background="#EEEEEE"/>

    <!-- 数据行2 -->
    <TableRow
        android:background="@android:color/white"
        android:padding="10dp">

        <TextView
            android:text="李四"
            android:textSize="14sp"
            android:gravity="center"/>

        <TextView
            android:text="78"
            android:textSize="14sp"
            android:textColor="#FF9800"
            android:gravity="center"/>

        <TextView
            android:text="85"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

        <TextView
            android:text="90"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

    </TableRow>

    <!-- 分隔线 -->
    <View
        android:layout_height="1dp"
        android:background="#EEEEEE"/>

    <!-- 数据行3 -->
    <TableRow
        android:background="@android:color/white"
        android:padding="10dp">

        <TextView
            android:text="王五"
            android:textSize="14sp"
            android:gravity="center"/>

        <TextView
            android:text="92"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

        <TextView
            android:text="96"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

        <TextView
            android:text="89"
            android:textSize="14sp"
            android:textColor="#4CAF50"
            android:gravity="center"/>

    </TableRow>

    <!-- 分隔线 -->
    <View
        android:layout_height="2dp"
        android:background="#CCCCCC"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"/>

    <!-- 统计行(跨列显示) -->
    <TableRow
        android:background="#E8F5E9"
        android:padding="12dp">

        <TextView
            android:text="平均分统计"
            android:textSize="16sp"
            android:textStyle="bold"
            android:textColor="#2E7D32"
            android:layout_span="4"
            android:gravity="center"/>

    </TableRow>

    <TableRow
        android:background="@android:color/white"
        android:padding="10dp">

        <TextView
            android:text="平均分"
            android:textSize="14sp"
            android:gravity="center"/>

        <TextView
            android:text="88.3"
            android:textSize="14sp"
            android:textColor="#2196F3"
            android:gravity="center"/>

        <TextView
            android:text="89.7"
            android:textSize="14sp"
            android:textColor="#2196F3"
            android:gravity="center"/>

        <TextView
            android:text="90.3"
            android:textSize="14sp"
            android:textColor="#2196F3"
            android:gravity="center"/>

    </TableRow>

</TableLayout>

效果预览:

复制代码
┌──────────────────────────────────┐
│ 姓名 │ 语文 │ 数学 │ 英语 │ ← 标题行
├──────┼──────┼──────┼──────┤
│ 张三 │  95  │  88  │  92  │
├──────┼──────┼──────┼──────┤
│ 李四 │  78  │  85  │  90  │
├──────┼──────┼──────┼──────┤
│ 王五 │  92  │  96  │  89  │
├──────────────────────────────────┤
│        平均分统计                 │ ← 跨列
├──────┼──────┼──────┼──────┤
│ 平均 │ 88.3 │ 89.7 │ 90.3 │
└──────────────────────────────────┘

5.6 实战案例:计算器布局

xml 复制代码
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stretchColumns="*"
    android:padding="8dp"
    android:background="#263238">

    <!-- 显示屏 -->
    <TableRow
        android:layout_marginBottom="16dp">

        <TextView
            android:id="@+id/display"
            android:layout_span="4"
            android:text="0"
            android:textSize="48sp"
            android:textColor="@android:color/white"
            android:gravity="right|center_vertical"
            android:padding="24dp"
            android:background="#37474F"
            android:layout_height="120dp"/>

    </TableRow>

    <!-- 第一行按钮:C ÷ × ← -->
    <TableRow>
        <Button
            android:text="C"
            android:textSize="20sp"
            android:layout_margin="4dp"
            android:background="#EF5350"
            android:textColor="@android:color/white"/>

        <Button
            android:text="÷"
            android:textSize="20sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>

        <Button
            android:text="×"
            android:textSize="20sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>

        <Button
            android:text="←"
            android:textSize="20sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>
    </TableRow>

    <!-- 第二行:7 8 9 - -->
    <TableRow>
        <Button
            android:text="7"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="8"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="9"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="-"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>
    </TableRow>

    <!-- 第三行:4 5 6 + -->
    <TableRow>
        <Button
            android:text="4"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="5"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="6"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="+"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>
    </TableRow>

    <!-- 第四行:1 2 3 = -->
    <TableRow>
        <Button
            android:text="1"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="2"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="3"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="="
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#4CAF50"
            android:textColor="@android:color/white"/>
    </TableRow>

    <!-- 第五行:0跨2列 . = -->
    <TableRow>
        <Button
            android:text="0"
            android:textSize="24sp"
            android:layout_span="2"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="."
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#455A64"
            android:textColor="@android:color/white"/>

        <Button
            android:text="%"
            android:textSize="24sp"
            android:layout_margin="4dp"
            android:background="#546E7A"
            android:textColor="@android:color/white"/>
    </TableRow>

</TableLayout>

5.7 TableLayout的列属性详解

🔧 stretchColumns 拉伸列
xml 复制代码
<!-- 所有列平均拉伸 -->
<TableLayout android:stretchColumns="*">

<!-- 只拉伸第0列和第2列 -->
<TableLayout android:stretchColumns="0,2">

<!-- 只拉伸第1列 -->
<TableLayout android:stretchColumns="1">
🔧 shrinkColumns 收缩列
xml 复制代码
<!-- 当内容过多时,第1列自动收缩 -->
<TableLayout android:shrinkColumns="1">
🔧 collapseColumns 隐藏列
xml 复制代码
<!-- 隐藏第2列 -->
<TableLayout android:collapseColumns="2">

5.8 跨列显示技巧

xml 复制代码
<TableRow>
    <!-- 跨3列显示 -->
    <TextView
        android:text="这是跨3列的标题"
        android:layout_span="3"
        android:gravity="center"
        android:textSize="18sp"
        android:background="#E3F2FD"
        android:padding="12dp"/>
</TableRow>

<TableRow>
    <!-- 正常的3列 -->
    <TextView android:text="第1列"/>
    <TextView android:text="第2列"/>
    <TextView android:text="第3列"/>
</TableRow>

5.9 Java代码动态创建表格

java 复制代码
public class TableLayoutDemo extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        TableLayout tableLayout = new TableLayout(this);
        tableLayout.setStretchAllColumns(true);
        tableLayout.setPadding(16, 16, 16, 16);
        
        // 创建标题行
        TableRow headerRow = new TableRow(this);
        headerRow.setBackgroundColor(Color.parseColor("#2196F3"));
        
        String[] headers = {"姓名", "年龄", "职业"};
        for (String header : headers) {
            TextView tv = new TextView(this);
            tv.setText(header);
            tv.setTextColor(Color.WHITE);
            tv.setTextSize(16);
            tv.setGravity(Gravity.CENTER);
            tv.setPadding(12, 12, 12, 12);
            headerRow.addView(tv);
        }
        tableLayout.addView(headerRow);
        
        // 创建数据行
        String[][] data = {
            {"张三", "25", "工程师"},
            {"李四", "30", "设计师"},
            {"王五", "28", "产品经理"}
        };
        
        for (int i = 0; i < data.length; i++) {
            TableRow dataRow = new TableRow(this);
            dataRow.setBackgroundColor(
                i % 2 == 0 ? Color.WHITE : Color.parseColor("#F5F5F5")
            );
            
            for (String cell : data[i]) {
                TextView tv = new TextView(this);
                tv.setText(cell);
                tv.setTextSize(14);
                tv.setGravity(Gravity.CENTER);
                tv.setPadding(12, 12, 12, 12);
                dataRow.addView(tv);
            }
            
            tableLayout.addView(dataRow);
        }
        
        setContentView(tableLayout);
    }
}

5.10 TableLayout典型应用场景

应用场景 说明 示例
📊 数据表格 展示规则数据 成绩单、价格表
📅 日历界面 日期按表格排列 月历、课程表
🧮 计算器 按钮按行列排列 科学计算器
📝 表单布局 标签和输入框对齐 注册表单
🏪 商品对比 多个商品参数对比 电商对比页

🎲 六、GridLayout - 灵活的网格布局

6.1 GridLayout是什么?

GridLayout(网格布局) 是Android 4.0(API 14)引入的新布局,它将界面划分成行和列的网格,比TableLayout更加灵活强大。

6.2 GridLayout vs TableLayout

对比项 TableLayout GridLayout
引入版本 API 1 API 14
灵活性 较低 非常高
跨行支持 ❌ 不支持 ✅ 支持
权重支持 ❌ 不支持 ✅ 支持
性能 较好 更好
推荐度 ⭐⭐⭐ ⭐⭐⭐⭐⭐

6.3 GridLayout核心属性

属性 作用 使用示例
columnCount 总列数 android:columnCount="4"
rowCount 总行数 android:rowCount="5"
orientation 排列方向 android:orientation="horizontal"
layout_row 所在行 android:layout_row="0"
layout_column 所在列 android:layout_column="1"
layout_rowSpan 跨行数 android:layout_rowSpan="2"
layout_columnSpan 跨列数 android:layout_columnSpan="3"
layout_columnWeight 列权重 android:layout_columnWeight="1"
layout_rowWeight 行权重 android:layout_rowWeight="1"

6.4 实战案例:计算器界面(GridLayout版)

xml 复制代码
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="4"
    android:rowCount="6"
    android:padding="8dp"
    android:background="#263238">

    <!-- 第0行:显示屏(跨4列) -->
    <TextView
        android:id="@+id/display"
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_row="0"
        android:layout_column="0"
        android:layout_columnSpan="4"
        android:layout_columnWeight="1"
        android:text="0"
        android:textSize="48sp"
        android:textColor="@android:color/white"
        android:gravity="right|center_vertical"
        android:padding="16dp"
        android:background="#37474F"
        android:layout_margin="4dp"/>

    <!-- 第1行:C ÷ × ← -->
    <Button
        android:layout_row="1"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="C"
        android:textSize="20sp"
        android:background="#EF5350"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="1"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="÷"
        android:textSize="20sp"
        android:background="#546E7A"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="1"
        android:layout_column="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="×"
        android:textSize="20sp"
        android:background="#546E7A"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="1"
        android:layout_column="3"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="←"
        android:textSize="20sp"
        android:background="#546E7A"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <!-- 第2行:7 8 9 - -->
    <Button
        android:layout_row="2"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="7"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="2"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="8"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="2"
        android:layout_column="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="9"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="2"
        android:layout_column="3"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="-"
        android:textSize="24sp"
        android:background="#546E7A"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <!-- 第3行:4 5 6 + -->
    <Button
        android:layout_row="3"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="4"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="3"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="5"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="3"
        android:layout_column="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="6"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="3"
        android:layout_column="3"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="+"
        android:textSize="24sp"
        android:background="#546E7A"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <!-- 第4行:1 2 3 = (=跨2行) -->
    <Button
        android:layout_row="4"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="1"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="4"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="2"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="4"
        android:layout_column="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="3"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <!-- = 按钮跨2行 -->
    <Button
        android:layout_row="4"
        android:layout_column="3"
        android:layout_rowSpan="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:text="="
        android:textSize="24sp"
        android:background="#4CAF50"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <!-- 第5行:0跨2列 . -->
    <Button
        android:layout_row="5"
        android:layout_column="0"
        android:layout_columnSpan="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="0"
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

    <Button
        android:layout_row="5"
        android:layout_column="2"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:text="."
        android:textSize="24sp"
        android:background="#455A64"
        android:textColor="@android:color/white"
        android:layout_margin="4dp"/>

</GridLayout>

布局示意图:

复制代码
┌────────────────────────────┐
│         显示屏(跨4列)      │
├──────┬──────┬──────┬──────┤
│  C   │  ÷   │  ×   │  ←   │
├──────┼──────┼──────┼──────┤
│  7   │  8   │  9   │  -   │
├──────┼──────┼──────┼──────┤
│  4   │  5   │  6   │  +   │
├──────┼──────┼──────┤      │
│  1   │  2   │  3   │  =   │
├──────┴──────┼──────┤ (跨2行)
│      0      │  .   │      │
└─────────────┴──────┴──────┘

6.5 实战案例:九宫格相册

xml 复制代码
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:rowCount="3"
    android:padding="4dp"
    android:background="#F5F5F5">

    <!-- 9张图片,自动按3x3排列 -->
    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo1"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo2"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo3"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo4"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo5"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo6"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:layout_columnWeight="1"
        android:src="@drawable/photo7"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"/>

    <ImageView
		android:layout_width="0dp"
		android:layout_height="120dp"
		android:layout_columnWeight="1"
		android:src="@drawable/photo8"
		android:scaleType="centerCrop"
		android:layout_margin="2dp"/>               

效果预览:

复制代码
┌─────┬─────┬─────┐
│ 图1 │ 图2 │ 图3 │
├─────┼─────┼─────┤
│ 图4 │ 图5 │ 图6 │
├─────┼─────┼─────┤
│ 图7 │ 图8 │ 图9 │
└─────┴─────┴─────┘

6.6 实战案例:不规则网格布局

xml 复制代码
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="4"
    android:rowCount="4"
    android:padding="8dp">

    <!-- 大图:跨2行2列 -->
    <ImageView
        android:layout_row="0"
        android:layout_column="0"
        android:layout_rowSpan="2"
        android:layout_columnSpan="2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/featured"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#E3F2FD"/>

    <!-- 右上小图1 -->
    <ImageView
        android:layout_row="0"
        android:layout_column="2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/small1"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#C8E6C9"/>

    <!-- 右上小图2 -->
    <ImageView
        android:layout_row="0"
        android:layout_column="3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/small2"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#FFECB3"/>

    <!-- 右侧中间:跨2行1列 -->
    <ImageView
        android:layout_row="1"
        android:layout_column="2"
        android:layout_rowSpan="2"
        android:layout_columnSpan="2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/medium"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#FFCDD2"/>

    <!-- 底部3个小图 -->
    <ImageView
        android:layout_row="2"
        android:layout_column="0"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/small3"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#E1BEE7"/>

    <ImageView
        android:layout_row="2"
        android:layout_column="1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_rowWeight="1"
        android:layout_columnWeight="1"
        android:src="@drawable/small4"
        android:scaleType="centerCrop"
        android:layout_margin="4dp"
        android:background="#B2DFDB"/>

    <!-- 最后一行:跨4列的横幅 -->
    <TextView
        android:layout_row="3"
        android:layout_column="0"
        android:layout_columnSpan="4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_columnWeight="1"
        android:text="浏览更多精彩内容"
        android:textSize="18sp"
        android:textColor="@android:color/white"
        android:gravity="center"
        android:padding="16dp"
        android:background="#2196F3"
        android:layout_margin="4dp"/>

</GridLayout>

布局示意图:

复制代码
┌─────────────┬─────┬─────┐
│             │ 小1 │ 小2 │
│    大图     ├─────┴─────┤
│  (跨2×2)    │           │
├─────────────┤   中图    │
│ 小3 │ 小4   │  (跨2×2)  │
└─────┴───────┴───────────┘
┌───────────────────────────┐
│      浏览更多精彩内容      │
└───────────────────────────┘

6.7 GridLayout权重详解

🎯 列权重(columnWeight)
xml 复制代码
<!-- 三个按钮平分宽度 -->
<Button
    android:layout_width="0dp"
    android:layout_columnWeight="1"
    android:text="按钮1"/>

<Button
    android:layout_width="0dp"
    android:layout_columnWeight="1"
    android:text="按钮2"/>

<Button
    android:layout_width="0dp"
    android:layout_columnWeight="1"
    android:text="按钮3"/>

关键点:

  • 必须设置 layout_width="0dp" 权重才生效
  • 权重比例决定宽度分配
🎯 行权重(rowWeight)
xml 复制代码
<!-- 控件填满整个单元格 -->
<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_columnWeight="1"
    android:layout_rowWeight="1"
    android:src="@drawable/image"/>

6.8 Java代码动态创建GridLayout

java 复制代码
public class GridLayoutDemo extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 创建GridLayout
        GridLayout gridLayout = new GridLayout(this);
        gridLayout.setColumnCount(3);  // 3列
        gridLayout.setRowCount(3);     // 3行
        gridLayout.setPadding(16, 16, 16, 16);
        
        // 动态创建9个按钮
        for (int i = 0; i < 9; i++) {
            Button button = new Button(this);
            button.setText("按钮 " + (i + 1));
            button.setTextSize(16);
            
            // 设置GridLayout布局参数
            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            
            // 指定行列位置
            params.rowSpec = GridLayout.spec(i / 3, 1f);      // 行号,权重
            params.columnSpec = GridLayout.spec(i % 3, 1f);   // 列号,权重
            
            // 设置宽高为0,配合权重使用
            params.width = 0;
            params.height = GridLayout.LayoutParams.WRAP_CONTENT;
            
            // 设置外边距
            params.setMargins(8, 8, 8, 8);
            
            button.setLayoutParams(params);
            
            // 设置背景颜色(交替)
            if ((i / 3 + i % 3) % 2 == 0) {
                button.setBackgroundColor(Color.parseColor("#E3F2FD"));
            } else {
                button.setBackgroundColor(Color.parseColor("#C8E6C9"));
            }
            
            gridLayout.addView(button);
        }
        
        setContentView(gridLayout);
    }
}

6.9 GridLayout典型应用场景

应用场景 说明 优势
🧮 计算器 按钮规则排列,支持跨行列 比TableLayout更灵活
📷 相册九宫格 图片网格展示 自动适配屏幕
🎮 游戏界面 棋盘、关卡选择 精确控制位置
📱 App启动器 应用图标网格 类似Android桌面
🎨 调色板 颜色选择器 规整的网格布局

6.10 GridLayout常见问题

问题 原因 解决方案
控件大小不一致 未设置权重 添加 layout_columnWeight 和 layout_rowWeight
权重不生效 宽高未设置为0dp 设置 layout_width="0dp" 或 layout_height="0dp"
控件位置错乱 未指定行列位置 明确设置 layout_row 和 layout_column
跨行列不生效 Span属性设置错误 检查 layout_rowSpan 和 layout_columnSpan

⚠️ 七、AbsoluteLayout - 已废弃的绝对布局

7.1 为什么要学习已废弃的布局?

虽然AbsoluteLayout在Android 1.5(API Level 3)就被废弃了,但作为学习Android发展历程的一部分,了解它可以:

  1. 理解为什么被废弃:避免在新项目中犯类似错误
  2. 维护旧代码:可能遇到使用该布局的老项目
  3. 对比学习:更好地理解现代布局的优势

7.2 AbsoluteLayout是什么?

AbsoluteLayout(绝对布局) 通过精确的X、Y坐标来定位每个控件的位置。

7.3 核心属性

属性 作用 示例
layout_x X坐标(水平位置) android:layout_x="100dp"
layout_y Y坐标(垂直位置) android:layout_y="200dp"

坐标系统:

复制代码
(0,0) ─────────→ X轴
  │
  │
  │
  ↓
 Y轴

7.4 示例代码

xml 复制代码
<!-- ⚠️ 不推荐使用!仅供学习参考 -->
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位置(50, 50)"
        android:layout_x="50dp"
        android:layout_y="50dp"
        android:background="#FFCDD2"
        android:padding="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位置(150, 150)"
        android:layout_x="150dp"
        android:layout_y="150dp"
        android:background="#C8E6C9"
        android:padding="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位置(250, 250)"
        android:layout_x="250dp"
        android:layout_y="250dp"
        android:background="#FFECB3"
        android:padding="10dp"/>

</AbsoluteLayout>

7.5 为什么被废弃?

缺点 说明 影响
❌ 不适配不同屏幕 固定坐标在不同分辨率下显示不一致 在大屏幕上可能显示很小,小屏幕上可能超出范围
❌ 横竖屏切换问题 坐标不会自动调整 横屏时布局错乱
❌ 维护困难 每次调整都要重新计算坐标 开发效率低下
❌ 国际化困难 不同语言文本长度不同 固定坐标无法适应

7.6 替代方案

需求 推荐使用 原因
相对定位 RelativeLayout 自动适配屏幕
复杂布局 ConstraintLayout 最强大灵活
简单排列 LinearLayout 简单高效
网格布局 GridLayout 规整美观

7.7 对比示例

❌ 不好的做法(AbsoluteLayout)
xml 复制代码
<AbsoluteLayout>
    <Button
        android:layout_x="100dp"
        android:layout_y="200dp"
        android:text="登录"/>
    <!-- 在不同屏幕上位置固定,可能显示异常 -->
</AbsoluteLayout>
✅ 推荐做法(RelativeLayout)
xml 复制代码
<RelativeLayout>
    <Button
        android:layout_centerInParent="true"
        android:text="登录"/>
    <!-- 自动居中,适配所有屏幕 -->
</RelativeLayout>

🎯 八、布局选择指南与最佳实践

8.1 布局选择决策树

简单列表 中等复杂 非常复杂 是 否 是 否 开始选择布局 界面复杂度? LinearLayout 需要层叠效果? ConstraintLayout FrameLayout 规则表格? TableLayout/GridLayout RelativeLayout

8.2 各布局综合对比

布局 学习难度 性能 灵活性 推荐指数 适用场景
LinearLayout ⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ 简单列表、按钮组
RelativeLayout ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ 复杂界面、表单
FrameLayout ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ 层叠效果、遮罩
TableLayout ⭐⭐ ⭐⭐⭐ ⭐⭐ ⭐⭐⭐ 规则表格
GridLayout ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 网格、计算器
AbsoluteLayout ⭐ ⭐⭐⭐ ⭐ ❌ 已废弃

8.3 实际开发场景推荐

📱 登录界面
复制代码
推荐:LinearLayout (垂直排列)
理由:标题、输入框、按钮垂直排列,简单明了
<LinearLayout
    android:orientation="vertical"
    android:padding="24dp">
    
    <TextView android:text="登录"/>
    <EditText android:hint="用户名"/>
    <EditText android:hint="密码"/>
    <Button android:text="登录"/>
    
</LinearLayout>
📋 设置页面
复制代码
推荐:LinearLayout + RelativeLayout 嵌套
理由:每个设置项内部用RelativeLayout,整体用LinearLayout垂直排列
<LinearLayout android:orientation="vertical">
    <!-- 每个设置项 -->
    <RelativeLayout>
        <TextView android:layout_alignParentLeft="true" android:text="通知"/>
        <Switch android:layout_alignParentRight="true"/>
    </RelativeLayout>
    <RelativeLayout>
        <TextView android:layout_alignParentLeft="true" android:text="声音"/>
        <Switch android:layout_alignParentRight="true"/>
    </RelativeLayout>
</LinearLayout>
🎮 游戏界面
复制代码
推荐:FrameLayout (多层叠加)
理由:背景、游戏区、UI控件分层显示
<FrameLayout>
    <ImageView android:src="@drawable/background"/>  <!-- 背景层 -->
    <GameView/>  <!-- 游戏层 -->
    <LinearLayout android:layout_gravity="top">      <!-- UI层 -->
        <TextView android:text="分数: 100"/>
    </LinearLayout>
</FrameLayout>
🧮 计算器
复制代码
推荐:GridLayout
理由:按钮规则排列,支持跨行跨列
💬 聊天界面
复制代码
推荐:RelativeLayout
理由:顶部标题栏、底部输入栏、中间消息列表,相对定位最合适

8.4 布局嵌套最佳实践

✅ 推荐做法
xml 复制代码
<!-- 最多2-3层嵌套 -->
<LinearLayout>  <!-- 第1层 -->
    <RelativeLayout>  <!-- 第2层 -->
        <TextView/>
        <ImageView/>
    </RelativeLayout>
</LinearLayout>
❌ 不推荐做法
xml 复制代码
<!-- 过度嵌套(5层以上) -->
<LinearLayout>
    <LinearLayout>
        <LinearLayout>
            <LinearLayout>
                <LinearLayout>
                    <TextView/>  <!-- 第5层!性能差! -->
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

8.5 性能优化技巧

技巧 说明 效果
减少嵌套层级 尽量保持在3层以内 ⬆️ 提升渲染速度
使用merge标签 减少不必要的ViewGroup ⬆️ 减少层级
使用ViewStub 延迟加载不常用的视图 ⬆️ 加快启动速度
使用include 复用布局文件 ⬆️ 提高可维护性
避免过度绘制 移除不必要的背景 ⬆️ 提升流畅度
使用<merge>减少层级
xml 复制代码
<!-- child_layout.xml -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView android:text="标题"/>
    <Button android:text="按钮"/>
</merge>
<!-- activity_main.xml -->
<LinearLayout>
    <include layout="@layout/child_layout"/>
    <!-- merge会直接将内容合并到LinearLayout中,不增加层级 -->
</LinearLayout>

8.6 屏幕适配建议

方法 说明 示例
使用dp单位 密度无关像素,自动适配 android:layout_width="100dp"
使用权重 按比例分配空间 android:layout_weight="1"
使用限定符 不同屏幕使用不同布局 layout-land/, layout-sw600dp/
避免硬编码 不要写死尺寸 ❌ layout_width="200px"
不同屏幕方向的布局
复制代码
res/
  layout/              ← 默认布局(竖屏)
    activity_main.xml
  layout-land/         ← 横屏布局
    activity_main.xml
  layout-sw600dp/      ← 平板布局(最小宽度600dp)
    activity_main.xml

📝 九、综合实战案例

9.1 案例一:完整的登录界面

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F5F5F5">

    <!-- Logo和标题区域 -->
    <LinearLayout
        android:id="@+id/headerLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:orientation="vertical"
        android:padding="32dp"
        android:gravity="center">

        <ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:src="@drawable/logo"
            android:layout_marginBottom="16dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="欢迎登录"
            android:textSize="28sp"
            android:textColor="#333333"
            android:textStyle="bold"/>

    </LinearLayout>

    <!-- 登录表单区域 -->
    <LinearLayout
        android:id="@+id/formLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/headerLayout"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:layout_marginTop="32dp"
        android:orientation="vertical"
        android:background="@android:color/white"
        android:padding="24dp"
        android:elevation="4dp">

        <!-- 用户名输入框 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:background="#F5F5F5"
            android:padding="12dp"
            android:layout_marginBottom="16dp">

            <ImageView
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:src="@drawable/ic_user"
                android:layout_marginEnd="12dp"/>

            <EditText
                android:id="@+id/etUsername"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="请输入用户名"
                android:textSize="16sp"
                android:background="@null"
                android:inputType="text"/>

        </LinearLayout>

        <!-- 密码输入框 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:background="#F5F5F5"
            android:padding="12dp"
            android:layout_marginBottom="24dp">

            <ImageView
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:src="@drawable/ic_lock"
                android:layout_marginEnd="12dp"/>

            <EditText
                android:id="@+id/etPassword"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="请输入密码"
                android:textSize="16sp"
                android:background="@null"
                android:inputType="textPassword"/>

        </LinearLayout>

        <!-- 记住密码和忘记密码 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="24dp">

            <CheckBox
                android:id="@+id/cbRemember"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="记住密码"
                android:textSize="14sp"/>

            <View
                android:layout_width="0dp"
                android:layout_height="1dp"
                android:layout_weight="1"/>

            <TextView
                android:id="@+id/tvForgetPassword"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="忘记密码?"
                android:textSize="14sp"
                android:textColor="#2196F3"/>

        </LinearLayout>

        <!-- 登录按钮 -->
        <Button
            android:id="@+id/btnLogin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="登录"
            android:textSize="18sp"
            android:textColor="@android:color/white"
            android:background="#4CAF50"
            android:padding="14dp"
            android:layout_marginBottom="16dp"/>

        <!-- 第三方登录 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="或使用第三方登录"
            android:textSize="14sp"
            android:textColor="#999999"
            android:layout_gravity="center"
            android:layout_marginBottom="16dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center">

            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/ic_wechat"
                android:layout_margin="8dp"/>

            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/ic_qq"
                android:layout_margin="8dp"/>

            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/ic_weibo"
                android:layout_margin="8dp"/>

        </LinearLayout>

    </LinearLayout>

    <!-- 底部注册提示 -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:orientation="horizontal"
        android:layout_marginBottom="32dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="还没有账号?"
            android:textSize="14sp"
            android:textColor="#666666"/>

        <TextView
            android:id="@+id/tvRegister"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="立即注册"
            android:textSize="14sp"
            android:textColor="#2196F3"
            android:layout_marginStart="4dp"/>

    </LinearLayout>

</RelativeLayout>

9.2 案例二:商品详情页

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">

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

        <!-- 商品图片轮播区 -->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="400dp"
		   android:background="#F5F5F5">
            <!-- ViewPager轮播图 -->
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <!-- 轮播指示器 -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="16dp"
            android:orientation="horizontal"
            android:background="#80000000"
            android:padding="8dp">

            <View
                android:layout_width="8dp"
                android:layout_height="8dp"
                android:background="@drawable/dot_selected"
                android:layout_margin="4dp"/>

            <View
                android:layout_width="8dp"
                android:layout_height="8dp"
                android:background="@drawable/dot_normal"
                android:layout_margin="4dp"/>

            <View
                android:layout_width="8dp"
                android:layout_height="8dp"
                android:background="@drawable/dot_normal"
                android:layout_margin="4dp"/>

        </LinearLayout>

        <!-- 收藏按钮 -->
        <ImageView
            android:id="@+id/ivFavorite"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/ic_favorite"
            android:layout_gravity="top|right"
            android:layout_margin="16dp"
            android:padding="8dp"
            android:background="@drawable/bg_circle_white"/>

    </FrameLayout>

    <!-- 商品信息区 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:background="@android:color/white">

        <!-- 价格和标题 -->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp">

            <!-- 价格 -->
            <LinearLayout
                android:id="@+id/priceLayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:orientation="horizontal"
                android:gravity="center_vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="¥"
                    android:textSize="16sp"
                    android:textColor="#FF5722"/>

                <TextView
                    android:id="@+id/tvPrice"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="299"
                    android:textSize="32sp"
                    android:textColor="#FF5722"
                    android:textStyle="bold"/>

                <TextView
                    android:id="@+id/tvOriginalPrice"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="¥499"
                    android:textSize="14sp"
                    android:textColor="#999999"
                    android:layout_marginStart="8dp"/>

            </LinearLayout>

            <!-- 已售数量 -->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:text="已售 1000+ 件"
                android:textSize="14sp"
                android:textColor="#999999"/>

        </RelativeLayout>

        <!-- 商品标题 -->
        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="【新品上市】高品质无线蓝牙耳机,降噪效果好,续航时间长"
            android:textSize="18sp"
            android:textColor="#333333"
            android:lineSpacingExtra="4dp"
            android:layout_marginBottom="12dp"/>

        <!-- 标签 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="包邮"
                android:textSize="12sp"
                android:textColor="#FF5722"
                android:background="@drawable/bg_tag_red"
                android:padding="4dp"
                android:layout_marginEnd="8dp"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="7天无理由退换"
                android:textSize="12sp"
                android:textColor="#4CAF50"
                android:background="@drawable/bg_tag_green"
                android:padding="4dp"
                android:layout_marginEnd="8dp"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="正品保证"
                android:textSize="12sp"
                android:textColor="#2196F3"
                android:background="@drawable/bg_tag_blue"
                android:padding="4dp"/>

        </LinearLayout>

    </LinearLayout>

    <!-- 分隔线 -->
    <View
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="#F5F5F5"/>

    <!-- 选择规格区 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:background="@android:color/white">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选择规格"
            android:textSize="16sp"
            android:textColor="#333333"
            android:textStyle="bold"
            android:layout_marginBottom="12dp"/>

        <!-- 颜色选择 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="12dp">

            <TextView
                android:layout_width="80dp"
                android:layout_height="wrap_content"
                android:text="颜色:"
                android:textSize="14sp"
                android:textColor="#666666"/>

            <GridLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:columnCount="3">

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="黑色"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_selected"
                    android:layout_margin="4dp"/>

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="白色"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_normal"
                    android:layout_margin="4dp"/>

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="蓝色"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_normal"
                    android:layout_margin="4dp"/>

            </GridLayout>

        </LinearLayout>

        <!-- 容量选择 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:layout_width="80dp"
                android:layout_height="wrap_content"
                android:text="容量:"
                android:textSize="14sp"
                android:textColor="#666666"/>

            <GridLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:columnCount="3">

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="64GB"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_selected"
                    android:layout_margin="4dp"/>

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="128GB"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_normal"
                    android:layout_margin="4dp"/>

                <TextView
                    android:layout_width="0dp"
                    android:layout_columnWeight="1"
                    android:layout_height="wrap_content"
                    android:text="256GB"
                    android:textSize="14sp"
                    android:gravity="center"
                    android:padding="8dp"
                    android:background="@drawable/bg_spec_normal"
                    android:layout_margin="4dp"/>

            </GridLayout>

        </LinearLayout>

    </LinearLayout>

    <!-- 分隔线 -->
    <View
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="#F5F5F5"/>

    <!-- 商品详情 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:background="@android:color/white">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="商品详情"
            android:textSize="16sp"
            android:textColor="#333333"
            android:textStyle="bold"
            android:layout_marginBottom="12dp"/>

        <!-- 参数表格 -->
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:stretchColumns="1"
            android:background="#F5F5F5">

            <TableRow
                android:padding="12dp"
                android:background="@android:color/white">

                <TextView
                    android:text="品牌"
                    android:textSize="14sp"
                    android:textColor="#666666"
                    android:layout_width="100dp"/>

                <TextView
                    android:text="Apple"
                    android:textSize="14sp"
                    android:textColor="#333333"/>

            </TableRow>

            <View
                android:layout_height="1dp"
                android:background="#F5F5F5"/>

            <TableRow
                android:padding="12dp"
                android:background="@android:color/white">

                <TextView
                    android:text="型号"
                    android:textSize="14sp"
                    android:textColor="#666666"/>

                <TextView
                    android:text="AirPods Pro 2"
                    android:textSize="14sp"
                    android:textColor="#333333"/>

            </TableRow>

            <View
                android:layout_height="1dp"
                android:background="#F5F5F5"/>

            <TableRow
                android:padding="12dp"
                android:background="@android:color/white">

                <TextView
                    android:text="续航时间"
                    android:textSize="14sp"
                    android:textColor="#666666"/>

                <TextView
                    android:text="6小时(单次)/ 30小时(充电盒)"
                    android:textSize="14sp"
                    android:textColor="#333333"/>

            </TableRow>

            <View
                android:layout_height="1dp"
                android:background="#F5F5F5"/>

            <TableRow
                android:padding="12dp"
                android:background="@android:color/white">

                <TextView
                    android:text="防水等级"
                    android:textSize="14sp"
                    android:textColor="#666666"/>

                <TextView
                    android:text="IPX4"
                    android:textSize="14sp"
                    android:textColor="#333333"/>

            </TableRow>

        </TableLayout>

        <!-- 详情图片 -->
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/product_detail"
            android:adjustViewBounds="true"
            android:layout_marginTop="16dp"/>

    </LinearLayout>

    <!-- 底部占位,防止被底部栏遮挡 -->
    <View
        android:layout_width="match_parent"
        android:layout_height="80dp"/>

</LinearLayout>

9.3 案例三:设置页面

xml 复制代码
<?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="vertical"
    android:background="#F5F5F5">

    <!-- 标题栏 -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="#4CAF50"
        android:elevation="4dp">

        <ImageView
            android:id="@+id/ivBack"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:src="@drawable/ic_back"
            android:padding="12dp"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="设置"
            android:textSize="20sp"
            android:textColor="@android:color/white"
            android:textStyle="bold"
            android:layout_centerInParent="true"/>

    </RelativeLayout>

    <ScrollView
        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:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="账户设置"
                android:textSize="14sp"
                android:textColor="#999999"
                android:padding="16dp"
                android:paddingStart="16dp"/>

            <!-- 个人信息 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_person"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="个人信息"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <ImageView
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:src="@drawable/ic_arrow_right"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"/>

            </RelativeLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#F5F5F5"
                android:layout_marginStart="52dp"/>

            <!-- 修改密码 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_lock"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="修改密码"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <ImageView
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:src="@drawable/ic_arrow_right"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"/>

            </RelativeLayout>

            <!-- 通知设置分组 -->
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="通知设置"
                android:textSize="14sp"
                android:textColor="#999999"
                android:padding="16dp"
                android:layout_marginTop="8dp"/>

            <!-- 消息通知开关 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_notification"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="消息通知"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <Switch
                    android:id="@+id/switchNotification"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:checked="true"/>

            </RelativeLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#F5F5F5"
                android:layout_marginStart="52dp"/>

            <!-- 声音开关 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_sound"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="声音"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <Switch
                    android:id="@+id/switchSound"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:checked="true"/>

            </RelativeLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#F5F5F5"
                android:layout_marginStart="52dp"/>

            <!-- 震动开关 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_vibrate"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="震动"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <Switch
                    android:id="@+id/switchVibrate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:checked="false"/>

            </RelativeLayout>

            <!-- 其他设置分组 -->
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="其他"
                android:textSize="14sp"
                android:textColor="#999999"
                android:padding="16dp"
                android:layout_marginTop="8dp"/>

            <!-- 清除缓存 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_clean"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="清除缓存"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="23.5 MB"
                    android:textSize="14sp"
                    android:textColor="#999999"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"/>

            </RelativeLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#F5F5F5"
                android:layout_marginStart="52dp"/>

            <!-- 关于我们 -->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@android:color/white"
                android:paddingStart="16dp"
                android:paddingEnd="16dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_alignParentLeft="true"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_info"
                        android:layout_marginEnd="12dp"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="关于我们"
                        android:textSize="16sp"
                        android:textColor="#333333"/>

                </LinearLayout>

                <ImageView
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:src="@drawable/ic_arrow_right"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"/>

            </RelativeLayout>

            <!-- 退出登录按钮 -->
            <Button
                android:id="@+id/btnLogout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="退出登录"
                android:textSize="16sp"
                android:textColor="#FF5722"
                android:background="@android:color/white"
                android:padding="16dp"
                android:layout_margin="16dp"/>

        </LinearLayout>

    </ScrollView>

</LinearLayout>

📚 十、本章总结与复习要点

10.1 核心知识点回顾

🎯 六大布局特点总结
布局 一句话总结 记忆口诀
LinearLayout 线性排列,支持权重 排队买票,一个跟一个
RelativeLayout 相对定位,灵活多变 家具摆放,互相参照
FrameLayout 层层叠加,简单实用 扑克牌叠,后来居上
TableLayout 表格结构,规则排列 Excel表,行列分明
GridLayout 网格布局,最强大 棋盘格,精确控制
AbsoluteLayout 绝对定位,已废弃 坐标死板,不要使用

10.2 必须掌握的属性

LinearLayout必会属性
xml 复制代码
android:orientation="vertical"           <!-- 方向 -->
android:layout_weight="1"               <!-- 权重 -->
android:gravity="center"                <!-- 子控件对齐 -->
android:layout_gravity="center"         <!-- 自身对齐 -->
RelativeLayout必会属性
xml 复制代码
android:layout_centerInParent="true"    <!-- 父容器居中 -->
android:layout_alignParentTop="true"    <!-- 父容器顶部对齐 -->
android:layout_below="@id/view1"        <!-- 在控件下方 -->
android:layout_toRightOf="@id/view2"    <!-- 在控件右边 -->
GridLayout必会属性
xml 复制代码
android:columnCount="3"                 <!-- 列数 -->
android:rowCount="4"                    <!-- 行数 -->
android:layout_row="0"                  <!-- 所在行 -->
android:layout_column="1"               <!-- 所在列 -->
android:layout_columnSpan="2"           <!-- 跨列数 -->
android:layout_columnWeight="1"         <!-- 列权重 -->

10.3 期末考试高频考点

✅ 选择题常考点
  1. LinearLayout权重计算
  2. LinearLayout使用______属性来设置排列方向。(答案:orientation)
  3. GridLayout可以通过______属性实现跨列显示。(答案:layout_columnSpan)
  4. RelativeLayout中,______属性可以让控件在父容器中居中。(答案:layout_centerInParent)
  5. TableLayout中,______属性用于指定可拉伸的列。(答案:stretchColumns)
✅ 简答题常考点

Q1: 简述LinearLayout的权重(weight)机制及计算方法。

答:

  1. 权重用于按比例分配剩余空间
  2. 计算公式:实际大小 = 原始大小 + (剩余空间 × 权重比例)
  3. 使用时需设置layout_width或layout_height为0dp
  4. 权重比例 = 当前控件权重 / 所有控件权重总和

Q2: RelativeLayout和LinearLayout的区别是什么?各适用于什么场景?

答:

  • RelativeLayout :
    • 通过相对位置定位控件
    • 适合复杂界面,减少嵌套层级
    • 性能略差于LinearLayout
    • 适用场景:表单、复杂布局
  • LinearLayout :
    • 按线性方向排列控件
    • 简单易用,性能好
    • 可能需要多层嵌套
    • 适用场景:简单列表、按钮组

Q3: 为什么AbsoluteLayout被废弃?应该用什么替代?

答: 废弃原因:

  1. 不适配不同屏幕尺寸和分辨率
  2. 横竖屏切换时布局错乱
  3. 维护困难,修改需重新计算坐标
  4. 无法适应国际化需求

替代方案:

  • 简单定位:LinearLayout
  • 相对定位:RelativeLayout
  • 复杂布局:ConstraintLayout
✅ 编程题常考点

题目1:使用LinearLayout实现一个登录界面

要求:

  • 垂直排列
  • 包含标题、用户名输入框、密码输入框、登录按钮
  • 登录按钮占满宽度
xml 复制代码
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="24dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎登录"
        android:textSize="24sp"
        android:layout_gravity="center"
        android:layout_marginBottom="32dp"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        android:layout_marginBottom="16dp"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码"
        android:inputType="textPassword"
        android:layout_marginBottom="24dp"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"/>

</LinearLayout>

题目2:使用GridLayout实现一个3×3的九宫格

xml 复制代码
<GridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:rowCount="3"
    android:padding="8dp">

    <!-- 9个按钮,自动按3×3排列 -->
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_columnWeight="1"
        android:text="1"
        android:layout_margin="4dp"/>

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_columnWeight="1"
        android:text="2"
        android:layout_margin="4dp"/>

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_columnWeight="1"
        android:text="3"
        android:layout_margin="4dp"/>

    <!-- ...继续添加4-9按钮... -->

</GridLayout>

题目3:使用RelativeLayout实现顶部标题栏+底部按钮+中间内容的布局

xml 复制代码
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 顶部标题栏 -->
    <TextView
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentTop="true"
        android:text="标题"
        android:gravity="center"
        android:background="#4CAF50"/>

    <!-- 底部按钮 -->
    <Button
        android:id="@+id/bottomButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="确定"/>

    <!-- 中间内容 -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/titleBar"
        android:layout_above="@id/bottomButton"
        android:text="中间内容区域"
        android:gravity="center"/>

</RelativeLayout>

10.4 实战能力检测清单

在期末考试前,请确保你能够:

✅ 基础能力(必须掌握)
  • 能够说出六大布局的名称和基本特点
  • 能够使用LinearLayout实现垂直和水平排列
  • 理解并能计算LinearLayout的权重分配
  • 能够使用RelativeLayout实现相对定位
  • 能够使用FrameLayout实现层叠效果
  • 知道AbsoluteLayout为什么被废弃
✅ 进阶能力(重点掌握)
  • 能够熟练使用GridLayout实现网格布局
  • 能够使用TableLayout实现表格数据展示
  • 能够根据需求选择合适的布局类型
  • 能够合理嵌套布局实现复杂界面
  • 能够在Java代码中动态创建布局
✅ 高级能力(加分项)
  • 能够优化布局层级,减少嵌套
  • 能够使用merge标签优化性能
  • 理解不同布局的性能差异
  • 能够实现屏幕适配
  • 能够独立完成复杂页面布局

10.5 快速记忆口诀

复制代码
六大布局记心间,各有特点要牢记:

Linear线性排一排,
横竖方向orientation,
权重分配要记牢,
width设零weight才妙。

Relative相对定位强,
above below左右忙,
centerInParent最中央,
父容器内任你放。

Frame帧布局很简单,
控件叠加一层层,
layout_gravity定位置,
轮播遮罩都能用。

Table表格行和列,
stretchColumns要拉伸,
layout_span跨列显,
规则数据展示佳。

Grid网格最灵活,
columnCount定列数,
columnSpan跨列显,
计算器用它最合适。

Absolute已废弃,
坐标固定不灵活,
屏幕适配有问题,
千万不要再使用。

选择布局有诀窍,
简单用Linear最高效,
复杂界面Relative好,
层叠效果Frame不少,
表格Grid看需要,
性能优化记得好!

10.6 常见错误与解决方案

❌ 错误1:LinearLayout权重不生效
xml 复制代码
<!-- 错误写法 -->
<Button
    android:layout_width="wrap_content"
    android:layout_weight="1"/>

✅ 正确写法:

xml 复制代码
<Button
    android:layout_width="0dp"
    android:layout_weight="1"/>

原因:使用权重时,对应方向的尺寸必须设置为0dp。

❌ 错误2:RelativeLayout引用未定义的ID
xml 复制代码
<!-- 错误写法 -->
<TextView
    android:layout_below="@id/titleView"/>

<TextView
    android:id="@+id/titleView"/>

✅ 正确写法:

xml 复制代码
<!-- 先定义被引用的控件 -->
<TextView
    android:id="@+id/titleView"/>

<TextView
    android:layout_below="@id/titleView"/>

原因:RelativeLayout中引用的ID必须已经在前面定义过。

❌ 错误3:过度嵌套导致性能问题
xml 复制代码
<!-- 不推荐:5层嵌套 -->
<LinearLayout>
    <LinearLayout>
        <LinearLayout>
            <LinearLayout>
                <LinearLayout>
                    <TextView/>
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

✅ 优化方案:

xml 复制代码
<!-- 使用RelativeLayout减少嵌套 -->
<RelativeLayout>
    <TextView
        android:layout_centerInParent="true"/>
</RelativeLayout>
❌ 错误4:GridLayout权重不生效
xml 复制代码
<!-- 错误写法 -->
<Button
    android:layout_columnWeight="1"/>

✅ 正确写法:

xml 复制代码
<Button
    android:layout_width="0dp"
    android:layout_columnWeight="1"/>

原因:GridLayout使用权重时,也需要设置对应方向为0dp。

❌ 错误5:FrameLayout控件被遮挡
xml 复制代码
<!-- 问题:后添加的控件会覆盖先添加的 -->
<FrameLayout>
    <TextView android:text="我会被遮挡"/>
    <ImageView android:src="@drawable/cover"/>
</FrameLayout>

✅ 解决方案:

xml 复制代码
<!-- 调整添加顺序或使用layout_gravity -->
<FrameLayout>
    <ImageView 
        android:src="@drawable/background"
        android:layout_gravity="center"/>
    
    <TextView 
        android:text="我在最上层"
        android:layout_gravity="top|center_horizontal"/>
</FrameLayout>

10.7 期末复习时间规划建议

📅 考前7天复习计划

Day 1-2:基础巩固

  • 复习LinearLayout和RelativeLayout
  • 重点:权重计算、相对定位
  • 练习:实现3-5个简单界面

Day 3-4:进阶学习

  • 复习FrameLayout、TableLayout、GridLayout
  • 重点:层叠效果、表格布局、网格布局
  • 练习:实现计算器、表格界面

Day 5-6:综合应用

  • 复习布局嵌套技巧
  • 完成3个综合案例
  • 练习:登录界面、商品详情页、设置页面

Day 7:冲刺复习

  • 回顾易错点和重点知识
  • 快速过一遍所有布局特点
  • 模拟考试题目练习

10.8 实用工具推荐

🛠️ 布局预览工具
  1. Android Studio Layout Editor
    • 可视化拖拽设计
    • 实时预览不同屏幕尺寸
    • 自动生成XML代码
  2. Hierarchy Viewer
    • 查看布局层级
    • 分析性能问题
    • 优化布局结构
  3. Layout Inspector
    • 运行时查看布局
    • 调试布局问题
    • 查看实际渲染效果

10.9 学习资源推荐

📚 官方文档
🎥 视频教程
  • B站搜索:"Android布局详解"
  • 慕课网:Android UI设计课程
  • YouTube:Android Layout Tutorials
📖 推荐书籍
  • 《第一行代码 Android》- 郭霖
  • 《Android开发艺术探索》- 任玉刚
  • 《Android群英传》- 徐宜生

🎓 十一、课后作业与练习

11.1 基础练习题

练习1:权重计算题

题目: 一个水平LinearLayout,总宽度为1200dp,包含三个Button:

  • Button1:layout_width="100dp",layout_weight="1"
  • Button2:layout_width="200dp",layout_weight="2"
  • Button3:layout_width="100dp",layout_weight="1"

请计算每个Button的实际宽度。

答案:

复制代码
剩余空间 = 1200 - 100 - 200 - 100 = 800dp
总权重 = 1 + 2 + 1 = 4

Button1实际宽度 = 100 + (800 × 1/4) = 100 + 200 = 300dp
Button2实际宽度 = 200 + (800 × 2/4) = 200 + 400 = 600dp
Button3实际宽度 = 100 + (800 × 1/4) = 100 + 200 = 300dp

验证:300 + 600 + 300 = 1200dp ✓
练习2:布局选择题

为以下场景选择最合适的布局:

  1. 场景A :一个包含标题、两个输入框、一个按钮的垂直排列的登录界面
    • 答案:LinearLayout(orientation="vertical")
  2. 场景B :一个顶部有标题栏、底部有导航栏、中间是内容区域的主界面
    • 答案:RelativeLayout
  3. 场景C :一个图片上方显示半透明遮罩和文字的Banner
    • 答案:FrameLayout
  4. 场景D :一个3×4的数字键盘
    • 答案:GridLayout
  5. 场景E :一个展示学生成绩的表格
    • 答案:TableLayout

11.2 编程实战题

实战1:实现微信聊天界面布局

要求:

  1. 顶部:标题栏(固定56dp高度,显示"聊天")
  2. 底部:输入栏(包含输入框和发送按钮)
  3. 中间:消息列表区域(ScrollView包裹)
  4. 使用RelativeLayout实现

参考代码框架:

xml 复制代码
<RelativeLayout>
    <!-- 顶部标题栏 -->
    <LinearLayout android:id="@+id/titleBar" 
        android:layout_alignParentTop="true"/>
    
    <!-- 底部输入栏 -->
    <LinearLayout android:id="@+id/inputBar" 
        android:layout_alignParentBottom="true"/>
    
    <!-- 中间消息区 -->
    <ScrollView 
        android:layout_below="@id/titleBar"
        android:layout_above="@id/inputBar"/>
</RelativeLayout>
实战2:实现电商商品列表项

要求:

  1. 左侧:商品图片(100dp×100dp)
  2. 右侧上方:商品名称
  3. 右侧中间:商品价格(红色、粗体)
  4. 右侧下方:购买按钮
  5. 使用RelativeLayout实现

提示:

  • 图片使用layout_alignParentLeft
  • 右侧内容使用layout_toRightOf
  • 价格使用android:textColor="#FF5722"
实战3:实现计算器界面

要求:

  1. 使用GridLayout实现
  2. 4列5行布局
  3. 第一行:显示屏(跨4列)
  4. 其他行:数字和运算符按钮
  5. "0"按钮跨2列
  6. "="按钮跨2行

挑战:

  • 所有按钮使用权重平分空间
  • 按钮之间有4dp间距
  • 显示屏高度120dp

11.3 综合项目作业

项目:个人信息管理App界面

第一阶段:登录页面

  • 使用LinearLayout实现
  • 包含Logo、标题、输入框、登录按钮
  • 底部有"注册"和"忘记密码"链接

第二阶段:主界面

  • 使用RelativeLayout实现
  • 顶部导航栏
  • 中间内容区(使用ViewPager)
  • 底部Tab栏(4个图标按钮)

第三阶段:个人信息页

  • 使用LinearLayout + RelativeLayout嵌套
  • 头像和昵称区域
  • 多个设置项(每项包含图标、文字、箭头)

第四阶段:数据展示页

  • 使用TableLayout或GridLayout
  • 展示个人数据统计表格
  • 支持数据排序和筛选

提交要求:

  1. 完整的XML布局文件
  2. 布局层级不超过3层
  3. 适配不同屏幕尺寸
  4. 代码注释清晰

🎉 结语

🌟 恭喜你完成本章学习!

通过本章的学习,你已经:

✅ 掌握了Android六大基本布局的使用方法 ✅ 理解了每种布局的特点和适用场景 ✅ 学会了如何选择合适的布局实现界面 ✅ 能够嵌套使用多种布局创建复杂界面 ✅ 了解了布局优化和性能提升技巧

💪 继续学习的方向

学完布局后,建议按以下顺序继续学习:

  1. ConstraintLayout(现代布局的首选)
  2. 事件处理(让界面"动"起来)
  3. 自定义View(创建个性化控件)
  4. Material Design(遵循设计规范)
  5. RecyclerView(高效列表展示)

📝 期末备考建议

  1. 多练习:每种布局至少独立实现3个案例
  2. 多对比:理解不同布局的优缺点和使用场景
  3. 多思考:为什么要这样设计?有没有更好的方案?
  4. 多总结:整理易错点和重点知识
  5. 多复习:考前一周每天看一遍本教程

🎯 最后的叮嘱

布局是Android开发的基础,也是面试的高频考点。

不要死记硬背,要理解原理和应用场景。

多动手实践,遇到问题多思考多查资料。

相信经过系统学习,你一定能在期末考试中取得好成绩!


📞 学习交流

如果在学习过程中遇到问题,可以:

  1. 📖 查阅Android官方文档
  2. 🔍 搜索CSDN、Stack Overflow
  3. 👥 加入Android开发学习群
  4. 💬 向老师或同学请教
  5. 🎥 观看B站相关教学视频

记住:遇到问题不要慌,查阅文档、动手实践是最好的学习方法!


🎓 祝你期末考试顺利!加油!💪

如果本教程对你有帮助,请分享给更多需要的同学!

相关推荐
ychqsq1 小时前
201.春风
经验分享·职场和发展
xiaomu001231 小时前
高湿环境床垫湿度管理技术框架:湿度阈值、排湿结构与材料选型
经验分享·学习·学习方法
半摆烂日常2 小时前
低代码平台API对接实践:接口鉴权与数据同步的完整实现
android·低代码·rxjava
zhangrelay2 小时前
ROS项目设计案例智能大模型正经乱答案例
linux·笔记·学习·ubuntu·机器人
事圆则缓2 小时前
volatile 使用场景全解析:它能保证什么,又解决不了什么
android
probex_2 小时前
学习笔记:知识图谱是什么,在测试里能干什么
笔记·学习·知识图谱
总线通信小百科2 小时前
汽车以太网交换器怎么选?先分清媒体转换器与多端口交换机
经验分享
以为你知道啊3 小时前
90年代复古博客
笔记
蒲公英内测分发3 小时前
智能投影仪参加海外展会,未上架的 Android 配套 App 怎么让客户限时试用?
android
ii_best3 小时前
按键精灵手机端开发安卓版实战:手写一个可最小化、可拖动的「运行日志悬浮窗」(附完整 源码 + 踩坑记录)
android·ios·智能手机·自动化·ai编程·按键精灵