本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
鸿蒙(HarmonyOS)开发中,屏幕适配需结合自适应布局、响应式设计、资源分级等技术,确保应用在不同设备(手机、平板、智慧屏等)上均能良好显示。
一、屏幕适配的核心方案
1. 自适应布局(ArkUI声明式开发)
通过弹性布局和动态尺寸单位实现UI自动拉伸与收缩。
常用API与属性
API/属性 | 作用 | 示例 |
---|---|---|
Flex 布局 | 弹性容器,控制子元素排列 | Flex({ direction: FlexDirection.Row }) |
width('100%') | 百分比宽度 | Text('内容').width('100%') |
layoutWeight | 权重分配剩余空间 | Text('左').layoutWeight(1) |
aspectRatio | 固定宽高比 | Image().aspectRatio(1.5) |
示例:基础自适应布局
@Entry
@Component
struct AdaptiveExample {
build() {
Column() {
// 顶部标题栏(固定高度)
Text('详情')
.height(50)
.width('100%')
.backgroundColor('#F2F2F2')
// 中间内容区(自适应高度)
Flex({ direction: FlexDirection.Row }) {
Image($r('app.media.product'))
.width('40%')
.aspectRatio(1)
Column() {
Text('商品名称').fontSize(18)
Text('¥199').fontColor('#FF0000')
}
.layoutWeight(1) // 占据剩余宽度
}
.padding(10)
// 底部按钮(固定高度)
Button('立即购买')
.width('80%')
.margin(20)
}
.height('100%')
}
}
2. 响应式布局(断点与栅格系统)
根据屏幕宽度(断点)或设备类型动态调整布局。
(1) 断点媒体查询
import { mediaQuery } from '@ohos.mediaquery';
@Entry
@Component
struct ResponsiveExample {
@State currentBreakpoint: string = 'sm'; // 默认小屏
aboutToAppear() {
// 监听屏幕变化
mediaQuery.on('(320vp <= width < 600vp)', (result: mediaQuery.MediaQueryResult) => {
if (result.matches) this.currentBreakpoint = 'sm';
});
mediaQuery.on('(600vp <= width < 840vp)', (result) => {
if (result.matches) this.currentBreakpoint = 'md';
});
}
build() {
// 根据断点显示不同布局
if (this.currentBreakpoint === 'sm') {
return this.buildMobileLayout();
} else {
return this.buildTabletLayout();
}
}
// 手机布局(单列)
@Builder buildMobileLayout() {
Column() {
Text('移动端视图').fontSize(16)
}
}
// 平板布局(双列)
@Builder buildTabletLayout() {
Row() {
Column() { Text('左侧菜单').width('30%') }
Column() { Text('主内容区').width('70%') }
}
}
}
(2) 栅格系统(GridRow/GridCol)
@Entry
@Component
struct GridExample {
build() {
GridRow({ columns: 12 }) { // 12列栅格
GridCol({ span: { sm: 12, md: 6 } }) { // 小屏占12列,中屏占6列
Text('区块1').backgroundColor('#F5F5F5')
}
GridCol({ span: { sm: 12, md: 6 } }) {
Text('区块2').backgroundColor('#EEEEEE')
}
}
}
}
3. 资源分级管理
按设备类型提供差异化资源(图片、字符串、布局等)。
(1) 目录结构
resources/
├── base/ # 默认资源
│ ├── element/ # 字符串
│ └── media/ # 图片
├── mobile/ # 手机专属
└── tablet/ # 平板专属
(2) 资源调用示例
// 图片自动匹配设备类型
Image($r('app.media.logo'))
// 字符串适配
Text($r('app.string.welcome'))
4. 字体与单位适配
- 使用vp(虚拟像素):
1vp ≈ 屏幕物理像素 / 160
,自动缩放。Text('适配文本').fontSize(16) // 16vp
- 动态计算尺寸: 根据屏幕密度调整:
import { display } from '@ohos.display'; const density = display.getDefaultDisplaySync().density; const realPx = 16 * density; // vp转物理像素
二、完整适配流程
-
设计阶段
- 使用Figma/Sketch设计多尺寸稿(360×640、768×1024等)。
- 标注关键断点(如600vp、840vp)。
-
开发阶段
- 优先使用弹性布局(Flex+百分比)。
- 对复杂组件实现响应式逻辑(如
@Builder
构建多布局)。 - 按设备类型提供资源(
resources/mobile/
vsresources/tablet/
)。
-
测试阶段
- 使用DevEco Studio的多设备预览功能。
- 真机测试覆盖手机、平板、折叠屏等设备。
三、常见问题
问题 | 原因 | 解决方案 |
---|---|---|
布局错乱 | 未使用vp单位 | 替换所有px 为vp |
图片模糊 | 未提供高分辨率资源 | 在resources/base/media/ 下提供2x/3x图 |
平板显示手机布局 | 未监听断点变化 | 添加mediaQuery 监听逻辑 |
四、总结
- 优先使用声明式布局:避免直接操作DOM,利用ArkUI自动适配能力。
- 极限测试:在最小(320vp)和最大(1280vp)屏幕上验证UI。
- 动态隐藏元素:对折叠屏展开/折叠状态使用
visibility
属性控制显示。
通过以上方法,鸿蒙应用可实现“一次开发,多端适配”。