
摘要
随着 HarmonyOS 设备生态不断丰富,从手表、手机到大屏电视和平板,应用如何在不同尺寸、不同比例的设备上保持优秀的用户体验,成了开发者绕不开的课题。响应式设计 就是解决这一问题的关键。ArkUI 提供了多种适配方案,支持开发者实现真正的多端统一体验。
引言:设备屏幕千变万化,我们不能"写死"UI
传统 UI 开发中,开发者常常会"写死"组件的宽高位置,但在 ArkUI 的多设备场景下,这种方法注定走不远。比如同一个组件,在手机上显示刚刚好,放到平板或智慧屏上就会显得太小或太大,影响体验。
ArkUI 提供了一整套响应式工具,包括 Flex 布局、媒体查询、视口单位(vw/vh)、自适应容器等,帮助我们构建"懂设备"的 UI。
核心响应式能力盘点
使用 Flex 布局实现弹性适配
Flex 是最常用也最实用的布局方式之一。它可以让元素根据父容器自动换行、对齐、调整大小,尤其适合横向或纵向排列的内容。
ts
@Entry
@Component
struct FlexLayoutExample {
build() {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
Text('菜单').fontSize(20)
Text('设置').fontSize(20)
Text('我的').fontSize(20)
}
.width('100%')
.padding(10)
.backgroundColor('#f0f0f0')
}
}
三点说明:
justifyContent: SpaceAround
表示元素之间平均分布,适合横向菜单。.width('100%')
是关键:父容器宽度变化,内部内容自动重排。.fontSize(20)
也可以设置成响应式变量,适配更小屏设备。
使用媒体查询实现精细适配
ArkUI 的 MediaQuery
可以监听屏幕宽度等参数,从而动态调整布局和样式。
示例场景:不同屏幕大小加载不同的布局组件
ts
@Entry
@Component
struct MediaQueryExample {
build() {
MediaQuery.of(this.context).then(info => {
let isTablet = info.width >= 720
if (isTablet) {
Column() {
Text('欢迎使用大屏版').fontSize(28)
Image($r('app.media.bigBanner')).width('90%')
}
} else {
Column() {
Text('欢迎使用手机版').fontSize(20)
Image($r('app.media.smallBanner')).width('100%')
}
}
})
}
}
亮点:
- 使用
MediaQuery.of(context)
获取屏幕宽度。 - 通过条件语句加载不同 UI 布局,灵活适配大屏与小屏。
实战场景:构建一个响应式电商首页模块
场景 1:根据屏幕大小切换商品展示方式(列表或网格)
小屏设备采用列表样式,大屏采用网格展示更多商品
ts
@Entry
@Component
struct ProductList {
build() {
MediaQuery.of(this.context).then(info => {
if (info.width < 600) {
List() {
ForEach(this.products, (item) => {
ListItem() {
Text(item.name).fontSize(18)
}
})
}
} else {
Grid({ columns: 3 }) {
ForEach(this.products, (item) => {
GridItem() {
Text(item.name).fontSize(20)
}
})
}
}
})
}
private products = [
{ name: 'T恤' },
{ name: '卫衣' },
{ name: '短裤' },
{ name: '运动鞋' },
{ name: '休闲裤' },
]
}
场景 2:顶部 Banner 根据视口单位自动缩放
ts
@Entry
@Component
struct ResponsiveBanner {
build() {
Image($r('app.media.banner'))
.width('100vw')
.height('30vh')
.objectFit(ImageFit.Cover)
.borderRadius(8)
}
}
分析:
vw
(视口宽度单位)和vh
(视口高度单位)能让 Banner 根据屏幕尺寸动态缩放,不管你是横屏、竖屏还是电视都能合适显示。objectFit: Cover
避免图片被拉伸变形。
常见问题 QA
Q1:我可以在 ArkUI 中组合使用 Flex 和 MediaQuery 吗?
当然可以。MediaQuery 控制结构,Flex 控制布局,两者结合是最实用的组合拳,尤其适合多列布局切换、内容隐藏等。
Q2:百分比和视口单位可以混用吗?
可以。ArkUI 支持像素(px)、百分比(%)、vw/vh 等多种单位混用,你可以用 width('80%')
搭配 height('30vh')
来适应不同场景。
Q3:有没有办法根据设备类型(手机/平板/电视)做精准适配?
你可以结合 DeviceInfo.deviceType
来做进一步判断。例如:
ts
if (DeviceInfo.deviceType == DeviceType.TV) {
// 加载电视专属 UI
}
总结
在 ArkUI 中做响应式设计并不复杂,但需要有意识地选用灵活的布局方式,比如 Flex、Grid,配合 MediaQuery 和视口单位,再搭配组件的自适应特性,基本可以覆盖大多数多屏适配场景。
写一次布局,跑全家桶设备,不再是梦想。如果你正在做适配工作,不妨从 Flex + MediaQuery 入手,多试试 vw/vh 的效果,相信你会爱上这种"动起来"的 UI!