【OpenHarmony/HarmonyOs 】响应式布局适配手机、平板与折叠屏:ResponsiveUtils 实战
·
【OpenHarmony/HarmonyOs 】响应式布局适配手机、平板与折叠屏:ResponsiveUtils 实战
HarmonyOS 应用经常需要面对多种设备:手机、平板、折叠屏,甚至更大的屏幕。学习类 App 尤其适合多端使用:手机刷题,平板看报纸,折叠屏一边看知识点一边答题。本文结合 政治视界 项目的 ResponsiveUtils.ets,详细讲解 ArkTS 中如何做响应式布局 📱
一、为什么不能只按手机设计
如果把手机页面直接拉伸到平板,会出现几个问题:
- 卡片过宽,阅读不舒服;
- 内容密度太低;
- 页面留白过多;
- 筛选栏和列表无法充分利用横向空间;
- 折叠屏展开后体验像放大的手机。
所以项目中单独封装了响应式工具类,统一判断屏幕宽度、断点、布局模式。
二、设备和断点定义
ResponsiveUtils.ets 中定义了设备类型和断点:
export enum ScreenBreakpoint {
SM = 'sm',
MD = 'md',
LG = 'lg',
XL = 'xl'
}
export enum LayoutMode {
COMPACT = 'compact',
REGULAR = 'regular',
EXPANDED = 'expanded'
}
断点用于判断屏幕大小,布局模式用于决定页面怎么排版:
COMPACT:手机竖屏,单列;REGULAR:横屏或小平板,适度增加内容宽度;EXPANDED:大平板或折叠屏展开,适合双列。
三、初始化屏幕信息
工具类初始化时读取屏幕信息:
private async initScreenInfo(): Promise<void> {
const displayInfo = await display.getDefaultDisplaySync();
this.screenWidth = px2vp(displayInfo.width);
this.screenHeight = px2vp(displayInfo.height);
this.screenDensity = displayInfo.densityDPI / 160;
this.isLandscape = this.screenWidth > this.screenHeight;
this.updateBreakpoint();
this.updateDeviceType();
this.updateLayoutMode();
this.setupFoldListener();
}
这里把像素转成 vp,是因为 ArkUI 布局更适合用 vp 做适配。
四、布局模式判断
核心判断逻辑如下:
private updateLayoutMode(): void {
if (this.isFoldable && this.foldState === 2) {
this.layoutMode = LayoutMode.EXPANDED;
} else if (this.screenWidth >= 840) {
this.layoutMode = LayoutMode.EXPANDED;
} else if (this.screenWidth >= 600 || this.isLandscape) {
this.layoutMode = LayoutMode.REGULAR;
} else {
this.layoutMode = LayoutMode.COMPACT;
}
}
这段代码体现了一个思路:不要只判断设备名称,而要判断可用空间。折叠屏展开后,即使仍是移动设备,也应该使用大屏布局。
五、页面中使用响应式参数
各页面都维护类似状态:
@State private responsiveInfo: ResponsiveInfo = responsive.getResponsiveInfo();
@State private isTwoColumn: boolean = false;
@State private contentPadding: number = 16;
@State private cardRadius: number = 20;
@State private titleFontSize: number = 24;
页面出现时更新参数:
private updateResponsiveParams(): void {
this.isTwoColumn = responsive.shouldShowTwoColumn();
this.contentPadding = responsive.getHorizontalPadding();
this.cardRadius = responsive.getBorderRadius('lg');
this.titleFontSize = responsive.getFontSize('xl') + 4;
}
这样页面里的 padding、圆角、字号、布局列数都能跟随设备变化。
六、监听屏幕变化
页面注册监听器:
aboutToAppear(): void {
this.updateResponsiveParams();
responsive.addListener(this.onResponsiveChange);
}
aboutToDisappear(): void {
responsive.removeListener(this.onResponsiveChange);
}
private onResponsiveChange = (info: ResponsiveInfo): void => {
this.responsiveInfo = info;
this.updateResponsiveParams();
}
注意 aboutToDisappear() 中移除监听,否则页面销毁后仍可能收到回调,造成不必要的问题。
七、哪些页面适合双列
在政治视界中,双列布局特别适合:
- 首页:左侧学习统计,右侧推荐题和错题;
- 笔记:左侧笔记列表,右侧详情;
- 报纸:左侧文章列表,右侧文章内容;
- 闪卡:左侧筛选,右侧卡片;
- 学习报告:左侧概览,右侧分类统计。
手机上单列更适合快速操作,平板上双列更适合阅读和对比。
八、实现流程总结
定义断点和布局模式
↓
读取屏幕宽高与密度
↓
判断横竖屏和折叠状态
↓
根据宽度得到 COMPACT/REGULAR/EXPANDED
↓
页面订阅响应式变化
↓
更新 padding、字号、圆角、列数
九、实践建议
写响应式布局时,不建议每个页面都自己判断屏幕宽度。统一封装工具类更好:
- 阈值统一;
- 页面代码更干净;
- 后续调整断点只改一处;
- 折叠屏和横屏逻辑更容易复用。
十、结语
响应式布局不是简单适配屏幕,而是为不同设备重新组织信息。政治视界通过 ResponsiveUtils 把设备判断、断点、折叠屏状态和尺寸参数集中管理,让页面可以自然适配手机、平板和折叠屏。
HarmonyOS 的全场景能力给了学习 App 很大空间。做好响应式,就是迈向全场景学习体验的第一步 🚀

更多推荐



所有评论(0)