Skip to content

布局约束与尺寸单位

ArkTS 中的尺寸单位系统、约束类型、对齐方式等布局基础概念。


1. 尺寸单位总览

单位全称说明适用场景
vpVirtual Pixel逻辑像素,根据 DPI 自动适配宽度/高度/间距(推荐
fpFont Pixel字体像素,根据系统字体缩放字号(推荐
pxPhysical Pixel物理像素,不随 DPI 变化边框宽度(谨慎使用
%Percentage占父容器的百分比响应式布局
autoAutomatic自动适配容器宽度/高度
match_parent匹配父容器等同于 '100%'全宽/全高

2. vp — 逻辑像素

2.1 概念

vp = dp = dip(Density-independent Pixel)

不同设备的物理像素(px)不同,但 vp 在视觉上是相同的
320px 的设备:1vp = 1px(DPI=160)
480px 的设备:1vp = 1.5px(DPI=240)
640px 的设备:1vp = 2px(DPI=320)

2.2 使用示例

typescript
// ✅ 推荐用 vp
Image('icon.png')
    .width(48vp)    // 图标大小
    .height(48vp)

Text('标题')
    .fontSize(24vp)   // ❌ 字号不应用 vp,应该用 fp
    .width(200vp)     // ✅

Button('提交')
    .width('100%')    // ✅ 响应式宽度
    .height(48vp)     // ✅ 固定高度

3. fp — 字体像素

3.1 概念

fp = 根据系统字体大小自动缩放的字体像素

用户修改系统字体大小 → fp 自动适配
用户修改系统字体大小 → vp 不变

3.2 使用规范

typescript
// ✅ 字号统一用 fp
Text('大标题')
    .fontSize(32fp)

Text('正文')
    .fontSize(16fp)

Text('辅助文字')
    .fontSize(12fp)

// ❌ 字号不用 vp 或 px
Text('标题')
    .fontSize(24vp)   // ❌ 不随系统字体缩放

4. px — 物理像素

4.1 什么时候用 px?

typescript
// ✅ 边框宽度:需要精确到 1 个物理像素
Row() {
    Text('左边')
    Divider()
        .strokeWidth(1px)  // ✅ 1px 细边框
    Text('右边')
}

// ❌ 其他场景不要用 px
Image('icon')
    .width(24px)  // ❌ 不同设备上显示大小不同

5. 约束类型

5.1 宽度约束

约束语法说明
固定宽度width(100)固定 100vp
百分比width('50%')占父容器的 50%
全宽width('100%')占满父容器
自动width('auto')根据内容自适应
填充width('match_parent')同 '100%'

5.2 高度约束

约束语法说明
固定高度height(60)固定 60vp
最小高度.minHeight(50)最小 50vp
最大高度.maxHeight(200)最大 200vp
百分比height('50%')占父容器的 50%

6. 对齐方式

6.1 主轴对齐(Row → 水平,Column → 垂直)

typescript
Row() {
    Text('A')
    Text('B')
    Text('C')
}
.justifyContent(FlexAlign.Start)    // 左对齐(Row)/ 顶对齐(Column)
.justifyContent(FlexAlign.Center)   // 居中
.justifyContent(FlexAlign.End)      // 右对齐(Row)/ 底对齐(Column)
.justifyContent(FlexAlign.SpaceAround)  // 每个元素两侧间距相等
.justifyContent(FlexAlign.SpaceBetween) // 两端对齐,间距相等

6.2 交叉轴对齐(Row → 垂直,Column → 水平)

typescript
Row() {
    Text('A')
        .height(100)    // A 更高
    Text('B')
        .height(50)
    Text('C')
        .height(75)
}
.alignItems(VerticalAlign.Start)  // 顶部对齐
.alignItems(VerticalAlign.Center) // 垂直居中
.alignItems(VerticalAlign.End)    // 底部对齐
.alignItems(VerticalAlign.Baseline) // 基线对齐

7. 边距与内边距

7.1 margin(外边距)

typescript
Text('Hello')
    .margin({
        top: 10,
        bottom: 10,
        left: 15,
        right: 15
    })

// 快捷写法
Text('Hello')
    .margin(10)           // 四周
    .margin({ top: 10 })  // 仅上边
    .margin({ left: 10, right: 10 })  // 左右

7.2 padding(内边距)

typescript
Button('点击')
    .padding({
        top: 10,
        bottom: 10,
        left: 20,
        right: 20
    })

8. 尺寸计算的优先级

优先级(从高到低):
1. 固定值(如 width(100))
2. 百分比(如 width('50%'))
3. 内容自适应(auto/match_parent)
4. flex 权重分配(flexGrow)

冲突解决

typescript
// ❌ 冲突:width 同时设置了固定值和百分比
Row() {
    Text('A').width(100).width('50%')  // 后者覆盖前者
}

// ✅ 正确:在不同组件上用不同约束
Row() {
    Text('固定')
        .width(100)          // 固定宽度
    Blank()                  // 填充中间
    Text('自适应')
        .width('100%')       // 百分比宽度
}

9. 单位转换工具

9.1 getFontScale()

typescript
import { window } from '@kit.ArkUI'

// 获取系统字体缩放比例
let fontScale = window.getWindowExtension().getFontScale()

// 手动将 vp 转换为 fp
function vpToFp(vp: number): number {
    return Math.round(vp * fontScale)
}

9.2 单位选择指南

元素推荐单位原因
宽度/高度vp适配不同 DPI
字号fp适配系统字体缩放
边框px精确像素
间距/边距vp视觉一致性
响应式宽度%自适应

10. 面试高频考点

Q1: vp、fp、px 的区别?

回答

  • vp:逻辑像素,根据 DPI 自动适配,用于宽/高/间距
  • fp:字体像素,根据系统字体缩放,用于字号
  • px:物理像素,不随 DPI 变化,仅用于边框宽度

Q2: Blank 组件的作用?

回答:在 Row/Column 中自动填充剩余空间,常用于"左边文字-右边图标"的两端对齐布局,或把内容推到屏幕底部。

Q3: justifyContent 有哪些对齐方式?

回答:Start、Center、End、SpaceAround、SpaceBetween。Row 对应水平方向,Column 对应垂直方向。


🐱 小猫提示:单位选择记住口诀——"宽高用 vp,字号用 fp,边框用 px,响应用 %"。这是面试中最基础的题。