当前位置: 首页 > news >正文

羽毛球工具 App HarmonyOS 6.0 实战(02/10):ArkUI 响应式布局

系列第 2 篇。本文聚焦一件事:不要为手机、平板、2in1 各写一套页面,而是在同一套业务页面上建立可维护的响应式外壳。

一、真实问题背景

羽毛球工具的使用场景天然跨设备:组织者可能用手机录入人员,场边可能用平板看对阵安排,2in1 设备适合横屏展示实时计分。如果只按手机竖屏设计,平板会显得空;如果按平板写死宽布局,手机又会拥挤。

当前项目在entry/src/main/module.json5中声明了phonetablet2in1。这不是为了“多写几个设备名”,而是让工程从配置层就承认多端体验是产品目标。

二、目标与边界

响应式适配要解决三个层次:

1. 设备宽度变化后,页面知道自己处在哪个断点。2. 主导航在小屏用底部 Tab,大屏用侧边导航。3. 业务页面内部使用相同状态,不因为布局切换丢数据。

边界是:本文不讲折叠屏姿态、不讲跨设备流转,也不讲手表端。这些属于后续协同体验文章。本文只讲当前 App 已经落地的 ArkUI 响应式基础。

三、断点系统设计

项目把断点监听放在common/src/main/ets/utils/BreakpointSystem.ets,而不是分散到每个页面。核心思路是:入口 Ability 初始化断点系统,断点变化写入AppStorage('currentBreakpoint'),页面通过@StorageProp读取。

private static smQuery: string = '(width<600vp)'; private static mdQuery: string = '(600vp<=width<840vp)'; private static lgQuery: string = '(840vp<=width<1080vp)'; private static xlQuery: string = '(1080vp<=width)'; BreakpointSystem.smListener = mediaquery.matchMediaSync(BreakpointSystem.smQuery); BreakpointSystem.smListener.on('change', (result: mediaquery.MediaQueryResult) => { if (result.matches) { BreakpointSystem.updateBreakpoint(BreakpointConstants.BREAKPOINT_SM); } });

这个方案的优点是低侵入。业务页面不需要自己维护窗口监听,也不需要把窗口对象层层传参。只要读取currentBreakpoint,就能决定布局密度、边距、列数和导航方式。

四、入口页面切换导航

entry/src/main/ets/pages/Index.ets是主壳页面。它用@StorageLink('active_tab_index')维护当前 Tab,用@StorageProp('currentBreakpoint')读取断点。

@StorageLink('active_tab_index') currentIndex: number = 0; @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'; isSmall(): boolean { return this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM; }

构建 UI 时,小屏走底部 Tab,大屏走左侧导航。业务内容通过PageContent()分发,首页、对阵、计分、排名、我的页仍然是同一批 features 组件。

if (this.isSmall()) { Column() { this.PageContent(); Row() { this.BottomTabItem(this.tabs[0], 0); this.BottomTabItem(this.tabs[1], 1); this.BottomTabItem(this.tabs[2], 2); this.BottomTabItem(this.tabs[3], 3); this.BottomTabItem(this.tabs[4], 4); } } } else { Row() { Column() { this.SideNavItem(this.tabs[0], 0); this.SideNavItem(this.tabs[1], 1); this.SideNavItem(this.tabs[2], 2); this.SideNavItem(this.tabs[3], 3); this.SideNavItem(this.tabs[4], 4); } this.PageContent(); } }

五、业务页面如何跟随

业务页面也读取currentBreakpoint。例如费用页、对阵页、排名页会根据断点调整 padding、最大宽度、卡片密度。我的页头像选择区域则进一步根据真实区域宽度计算列数,避免在平板上仍然按手机三列挤在一起。

相关源码包括:

-features/src/main/ets/home/HomePage.ets-features/src/main/ets/fee/FeeInputPage.ets-features/src/main/ets/stats/StatsPage.ets-features/src/main/ets/me/MePage.ets-common/src/main/ets/utils/BreakpointConstants.ets

这类页面适配最容易踩的坑是“只改外壳,不改内容”。外壳变宽后,如果内部仍然写死宽度或用过大的字号,平板体验依旧不自然。

六、取舍与风险

当前项目选择mediaquery + AppStorage,没有引入更复杂的设备类型判断。这样做的取舍是:宽度优先,逻辑简单,适合工具型 App;缺点是无法直接表达折叠态、悬浮窗态、外接屏状态。后续如果要做平板大屏记分牌或跨设备展示,需要增加更细的窗口上下文。

另一个风险是@Builder中读取响应式状态时,可能出现状态变化但局部组件不刷新的情况。项目的做法是尽量把依赖@StorageProp的布局判断放在主 build 分支,或者显式传参给 Builder。

七、构建验证

验证命令:

& 'D:\HuaweiDevelopFormalStudy\DevEco Studio\tools\hvigor\bin\hvigorw.bat' assembleHap --mode module -p product=default --no-daemon

验证时间:2026-06-28。当前结果为BUILD SUCCESSFUL。截图来自doc/screenshots_current/phonedoc/screenshots_current/tablet,用于证明不是只在代码里写了断点,而是真的覆盖了手机和平板两种显示状态。

八、官方参考

ArkUI 响应式布局和媒体查询能力应以官方文档为准,可从 HarmonyOS ArkUI 指南 进入,并结合当前 SDK 的@kit.ArkUIAPI 说明核对。

九、工程验收清单

-module.json5声明phone/tablet/2in1。-BreakpointSystem统一维护断点,不在每个页面重复监听。- 主壳页面小屏底部导航,大屏侧边导航。- 业务页面通过@StorageProp('currentBreakpoint')跟随布局。- 手机和平板截图都能对应到同一套源码。

十、小结

响应式布局不是把元素变大,也不是给平板加几个空白。更实用的方式是:状态统一、导航换形、内容调密度。这个羽毛球工具的实现还不复杂,但已经足够支撑后续跨设备文章:手机控制、平板展示、手表计分都可以继续复用这套状态和页面分层。

十一、下一篇衔接

下一篇讲本地优先数据方案:为什么这个 App 用Preferences + AppStorage管住对局、费用和设置,而不是让每个页面自己保存一份状态。

http://www.jsqmd.com/news/1098819/

相关文章:

  • Apache Commons Text RCE漏洞CVE-2022-42889:原理、复现与安全修复
  • 什么!翻译论文还要消耗token? 关于如何提升marker转英文文档速度,并使用skill批量翻译论文
  • 官方 API 与中转 API 选型实测指南
  • openEuler-portal-mcp智能推荐系统:如何实现100%工具推荐覆盖率
  • 广告创意提案怎么做?用多模型联动快速制作动态 Demo 提案实战与对比
  • VMware导入虚拟机失败?90%的运维人都踩过的7个隐藏陷阱及修复命令清单
  • 5大特色揭秘:ZR.Admin.NET企业级权限管理平台实战指南
  • 把 ES Repository 纳入 CMS 轨道,一套更稳的 SAP PI 内容传输治理方式
  • 羽毛球工具 App HarmonyOS 6.0 实战(03/10):本地优先数据方案
  • 从真实高可用链路看 SAP AEX local SLD 配置,别让 SLD 成为集群切换时的隐形单点
  • Kali Linux 渗透测试环境搭建:VMware 虚拟机安装配置全流程指南
  • Crypto方向 · RSA已知部分明文攻击(Coppersmith方法)
  • 浅谈C++重载、重写、重定义
  • YOLOv8知识蒸馏实战:从37%到42%mAP,无损提升轻量模型精度
  • Bebas Neue:开源字体设计的几何美学革命
  • 这门课程适合谁?
  • 紧急预警:VMware克隆未启用“Reconfigure after clone”将触发许可证异常——2024 Q3 VMware官方补丁前最后规避指南
  • C语言指针详解3
  • TVA:连接数字与物理世界的智能底座(5)
  • 工作原理:其核心是一个两步过程。
  • 防火墙Web界面配置一对一IPSec隧道:从原理到实战详解
  • Mineradio音乐播放器下载安装地址
  • 机顶盒B860AV2.1-M刷机攻略
  • 从 ABAP 后端到 AEX,Local Integration Engine 下的 Business System 配置全景
  • VR-Reversal:3D视频转2D的神奇工具,让沉浸式体验触手可及
  • AI渐进编程之四:状态机如何约束 AI 的动作?
  • WAF核心原理、部署模式与防护实战:从SQL注入到命令执行的安全防线
  • QoS详解:服务质量,如何优先保障关键业务的网络带宽
  • 【SI_GMSL2】深入了解示波器测试GMSL2眼图
  • 免费的Windows硬件检测工具合集,101款检测工具一站集齐,小白也能轻松上手 图吧工具箱Win UI3版