3. 布局基础

布局,说白了就是决定控件「站哪儿」的问题。

我刚入行那会儿,觉得布局很简单——拖几个控件到界面上不就完了?结果一到跨平台,Android 上好好的,iOS 上跑飞了。嗯,从那以后我才认真研究起布局的底层逻辑。

绝对定位:最直接,也最脆弱

绝对定位就是给控件一个固定的 x、y 坐标。比如在 Qt 里写:

button.setGeometry(100, 50, 120, 40)

这行代码的意思是:按钮左上角在 (100, 50),宽 120,高 40。

听起来很直观对吧?但我在项目中吃过它的亏。有一次做嵌入式界面,屏幕分辨率从 800x480 换到 1024x600,所有控件全错位了。改坐标改到怀疑人生。

避坑指南: 我曾经在一个医疗设备项目里全用绝对定位,结果客户临时要求支持横竖屏切换……那周我加了三天班。绝对定位只适合以下场景:
  • 原型快速验证
  • 固定尺寸的嵌入式屏幕
  • 游戏中的 HUD 元素

相对布局:让控件「互相商量」

相对布局的核心思想是:控件的位置是相对于其他控件或父容器来定的。

你想想看,如果我说「确定按钮在取消按钮右边 10 像素」,而不是「确定按钮在 (300, 200)」,是不是灵活多了?

在 Android 里,RelativeLayout 是这样用的:

<Button
    android:id="@+id/btn_ok"
    android:layout_toRightOf="@id/btn_cancel"
    android:layout_marginLeft="10dp" />

我个人习惯把相对布局用在表单里。比如「标签在输入框左边」、「错误提示在输入框下方」。这样不管屏幕怎么变,它们的关系始终不乱。

我的经验: 相对布局的嵌套层级别超过 3 层。超过 3 层,性能就开始往下掉。我见过一个同事嵌套了 7 层,界面滑动卡成 PPT。

水平布局与垂直布局:最常用的「排列工具」

这两个布局说白了就是「排排坐」。水平布局让控件从左到右排,垂直布局让控件从上到下排。

在 Flutter 里,水平布局用 Row,垂直布局用 Column:

Row(
  children: [
    Icon(Icons.star),
    Text('评分 4.8'),
    Spacer(),
    Text('¥ 29.9'),
  ],
)

你看,一行代码就把三个控件排好了。而且 Spacer 会自动把剩余空间吃掉,让价格跑到右边去。

我建议你记住一个原则:能用 Row/Column 解决的问题,就别用绝对定位。我在做跨平台项目时,90% 的布局需求靠这两个就能搞定。

布局类型 适用场景 常见坑点
水平布局 导航栏、标签页、按钮组 控件过多时溢出
垂直布局 列表、表单、文章内容 高度不够时滚动

网格布局:二维空间的「排兵布阵」

网格布局把界面分成行和列,每个控件占据一个或多个格子。它特别适合做计算器、相册、仪表盘这类规整的界面。

在 Qt 里,QGridLayout 是这样用的:

layout = QGridLayout()
layout.addWidget(button_1, 0, 0)  # 第0行第0列
layout.addWidget(button_2, 0, 1)  # 第0行第1列
layout.addWidget(button_3, 1, 0, 1, 2)  # 第1行,跨2列

为什么会用到「跨列」?你想想计算器上的「0」按钮,它通常比别的按钮宽一倍。网格布局处理这种需求就特别优雅。

核心要点: 网格布局的难点在于「合并单元格」。我建议你先在纸上画好网格草图,标清楚每个控件占几行几列,再写代码。别问我怎么知道的——我直接写过,然后改了三版。

表单布局:专为「标签+输入框」而生

表单布局是垂直布局的「专业版」。它自动把标签和输入框对齐,而且支持「必填标记」、「错误提示」等常见需求。

在 Qt 里,QFormLayout 用起来很简洁:

form = QFormLayout()
form.addRow('用户名:', username_input)
form.addRow('密码:', password_input)
form.addRow('', submit_button)

你看,左边是标签,右边是输入框,自动对齐。最后一行留空标签,让提交按钮独占一行。

我个人习惯在表单布局里加一个「必填项」的视觉提示。比如在标签前加红色星号,或者在输入框边框变红。用户一看就明白,不用多解释。

注意: 表单布局不适合复杂嵌套。如果你需要「地址」下面再分「省/市/区」,建议用网格布局或者自定义组合控件。我曾经硬用表单布局嵌套三层,结果对齐全乱了,最后全部重写。

知识体系总览

下面这张图帮你理清这五种布局的关系和选择逻辑:

布局选择决策树 你的布局需求 固定尺寸?→ 绝对定位 相对关系?→ 相对布局 排列方式?→ 看下面 一维排列 → 水平/垂直 二维网格 → 网格布局 标签+输入 → 表单布局 提示:实际项目中经常混合使用多种布局 比如:外层用垂直布局,内部某一行用水平布局

这张图的核心逻辑是:先问自己「屏幕尺寸固定吗?」——固定就用绝对定位,不固定就往下走。再问「控件之间有相对关系吗?」——有就用相对布局,没有就看排列方式。一维排列用水平/垂直,二维网格用网格布局,标签+输入框用表单布局。

我的建议: 别死记硬背。你只要记住「绝对定位最脆弱,表单布局最专业,其他三个看情况混用」就够了。实际项目中,我经常在一个界面里同时用垂直布局、水平布局和网格布局。比如:外层垂直滚动,每行用水平布局,中间某一块用网格布局展示数据。

好了,布局基础就聊到这儿。这些知识够你应付 80% 的跨平台布局场景了。剩下的 20%,靠的是经验积累和踩坑——嗯,我也还在继续踩。