ccai 2026-09-10 11:29:54 发布摘要
手机、平板、折叠屏和分屏窗口的可用宽度差异很大,固定宽高的页面在换屏或旋转后容易出现按钮挤压、卡片留白过多和滚动区域不合理等问题。本文以一个任务工作台为例,使用 ArkUI 的栅格布局能力,根据窗口宽度调整页面结构,并用少量状态处理交互差异。文章重点讨论布局规则、字体放大、安全区域和测试边界,不把“适配所有设备”作为未经验证的结论。
一、先把“手机版和平板版”改成窗口规则
最初的工作台只按约 360vp 宽的手机窗口设计,页面包含:
- 顶部标题和新增按钮;
- 中间的汇总卡片;
- 快捷操作区域;
- 最近任务列表。
当窗口变宽后,汇总卡片变成很长的横条;在折叠屏半屏状态下,标题和右侧按钮会争抢空间。问题不在于某一个控件的边距,而在于页面把“设备型号”当成了布局依据。
这次调整制定了三个规则:
- 使用窗口可用宽度,而不是判断具体机型;
- 窄窗口优先保证可操作性,宽窗口再利用多列空间;
- 旋转、分屏和字体放大后,重要内容不能被裁切。
断点 360vp、600vp 和 840vp 只是本例的起始值,正式项目应根据实际页面内容和目标设备重新验证。
二、用 GridRow/GridCol 搭建页面骨架
下面只展示核心布局。GridRow、GridCol 的对象参数和断点类型可能随 SDK 小版本变化,实际开发请以当前 DevEco Studio 的类型提示为准。
import { BreakpointsReference } from '@kit.ArkUI'
interface TaskItem {
id: string
title: string
done: boolean
}
@Entry
@Component
struct WorkbenchPage {
@State private compact: boolean = true
@State private tasks: TaskItem[] = [
{ id: '1', title: '整理本周会议记录', done: false },
{ id: '2', title: '检查发布清单', done: true }
]
build() {
Column({ space: 12 }) {
Row() {
Text('今日工作台')
.fontSize(this.compact ? 22 : 28)
.fontWeight(FontWeight.Medium)
Blank()
if (!this.compact) {
Button('批量操作')
.height(40)
.onClick(() => this.openBatchAction())
}
Button('新增')
.height(40)
.onClick(() => this.addTask())
}
.width('100%')
GridRow({
columns: 12,
gutter: { x: 12, y: 12 },
breakpoints: {
value: ['360vp', '600vp', '840vp'],
reference: BreakpointsReference.WindowSize
}
}) {
GridCol({ span: { xs: 12, sm: 12, md: 7, lg: 8 } }) {
SummaryCard({ taskCount: this.tasks.length })
}
GridCol({ span: { xs: 12, sm: 12, md: 5, lg: 4 } }) {
QuickActions({ compact: this.compact })
}
GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) {
RecentTaskList({ items: this.tasks })
}
}
.width('100%')
.onAreaChange((_oldArea, area) => {
this.updateCompact(area.width)
})
}
.width('100%')
.height('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
}
private updateCompact(width: number): void {
const next = width < 600
if (next !== this.compact) {
this.compact = next
}
}
private addTask(): void {
const item: TaskItem = {
id: makeId(), // 项目中使用可靠的唯一 ID 生成方式
title: '未命名任务',
done: false
}
this.tasks = [item, ...this.tasks]
}
private openBatchAction(): void {
// 交给业务层处理
}
}这个布局有几个值得注意的地方:
- 每个断点下的
GridCol.span总和不能超过 12; - 重要操作“新增”在窄屏仍保留文字,不只显示图标;
- 列表使用业务 ID 作为 key,不使用数组下标;
- 卡片内部尽量使用
width('100%'),避免继续写死宽度; - 页面只保留一个主要滚动容器,减少嵌套滚动冲突。
三、窄屏和宽屏的交互不必完全相同
自适应不只是改变列数,还包括交互取舍。
窄屏下可以:
- 将“批量操作”收进更多菜单;
- 减小标题字号,但保留足够的可读性;
- 保留主要按钮的文字和触控高度;
- 让表单在键盘弹出时仍可滚动到提交按钮。
宽屏下可以:
- 将汇总和快捷操作并排;
- 增加详情栏或预览区域;
- 让列表占满下一行;
- 在主从布局中同时显示列表和详情。
字体放大时也要重新检查卡片高度。不能因为默认字号下没有问题,就假设辅助功能设置下仍然不会溢出。
四、测试矩阵
发布前至少覆盖以下窗口和状态:
| 类别 | 用例 |
|---|---|
| 窗口宽度 | 360、600、840、1200vp 附近的窗口 |
| 方向 | 竖屏、横屏 |
| 形态 | 折叠半屏、展开、左右分屏 |
| 字体 | 默认字号、放大字号 |
| 数据 | 空列表、单条、几十条 |
| 系统区域 | 状态栏、导航区域、键盘弹出 |
| 操作 | 新增、删除、返回、重复点击 |
验收重点不是“看起来差不多”,而是:
- 是否出现横向滚动;
- 最后一条列表项是否被安全区域遮挡;
- 断点切换时是否出现明显跳动;
- 窗口连续拖动时是否产生大量无意义重绘;
- 主要操作是否仍然容易找到和点击。
五、容易忽略的坑
第一,不能直接照搬 Web 端的 Bootstrap 断点规则。ArkUI 的窗口参考系、单位和对象参数应以当前 SDK 文档为准。
第二,不能把某个机型的状态栏高度写成固定值。应使用当前 SDK 提供的安全区域能力。
第三,onAreaChange 在窗口连续变化时可能频繁触发。实际项目中只在跨过阈值时更新状态,避免每次尺寸变化都修改多个状态字段。
第四,响应式布局不能代替真实设备验证。栅格只是骨架,图片比例、文本长度、输入法和系统字体仍需要在目标设备上检查。
六、总结
这次实践的重点是把“手机版、平板版、折叠屏版”改写成可验证的窗口规则。先用 GridRow/GridCol 建立稳定骨架,再用少量状态处理交互差异,通常比为每一种设备维护一套页面更容易测试和维护。
相关推荐
ccai
我还没有写个人简介......
帖子
提问
粉丝
一笔加油费到月度报表:用 ArkTS 做一个离线优先的“车账本”
2026-09-18 17:38:18 发布大文件上传的断点续传:HarmonyOS 客户端与 Java 服务端协作
2026-09-18 17:36:40 发布

0
京公网安备:11010502051901号