【化学实验室|16】HarmonyOS ArkTS 多设备布局实战:适配手机、平板和 PC/2in1 的窗口变化

发布时间:2026/10/22 12:45:59
【化学实验室|16】HarmonyOS ArkTS 多设备布局实战:适配手机、平板和 PC/2in1 的窗口变化 在module.json5中写入phone、tablet和2in1只代表应用允许安装到这些设备并不等于页面已经完成多设备适配。真正的风险通常出现在窗口变化之后平板竖屏显示正常横屏却只把手机列表拉得更宽PC 自由窗口缩小时“我的”页面底部卡片无法滚动首页从两列切成三列后热门实验数量增加到 8 个但 Grid 仍保持手机高度第三行内容被裁切系统字体放大后固定高度 Banner 内按钮挤出容器。本文基于化学实验室 1.0.5的真实 HarmonyOS ArkTS 源码展开。工程的entry/src/main/module.json5明确声明deviceTypes: [ phone, tablet, 2in1 ]主入口Index.ets始终使用 56vp 底部 TabsHomePage.ets和LearningPage.ets通过onAreaChange()读取宽度在 600vp 与 840vp 处调整 Grid 列数LabPage.ets始终显示单列实验列表MinePage.ets使用不可滚动的根 Column。当前实现已经迈出响应式第一步但各页面对窗口的理解不同部分固定尺寸没有随内容重算。本文不按设备名称复制三套页面而是建立一份可测试的WindowProfile窗口宽高先映射为 compact、medium、expanded 三种布局能力再由导航壳、内容网格、列表分栏和输入反馈分别消费。同一应用在手机旋转、平板分屏、PC 自由窗口缩放时都按实际可用内容宽度重排。多设备适配不是根据设备名称复制页面而是把窗口宽度映射成稳定布局能力再让每个业务区在同一能力下重排、限宽和保留可达操作。CHEM-LAB-ONE12-MULTIDEVICE-WINDOW-PROFILE-20260730本文将完成以下内容核对工程真实设备声明与五个主页面布局。解释设备类型、屏幕尺寸和窗口尺寸的区别。复现首页 medium 宽度下 Grid 高度与行数不匹配的问题。建立统一的 compact、medium、expanded 窗口等级。让首页和学习页共享列数、间距和内容宽度规则。为实验室设计单列到列表详情分栏的渐进布局。让“我的”页面在横屏和小窗口中保持全部操作可达。为 expanded 窗口增加限宽避免内容无限拉伸。补齐鼠标悬停、键盘焦点和触摸目标验证。给出旋转、分屏、自由窗口和字体放大的测试矩阵。一、设备声明只说明分发范围当前module.json5把 phone、tablet 和 2in1 都列入deviceTypes。这意味着发布材料、截图组、交互方式和运行验证都要覆盖三类目标但页面不会因为这个数组自动从单列变成分栏。同一设备上还会出现多个窗口状态手机竖屏与横屏。折叠屏折叠与展开。平板全屏、分屏和悬浮窗。PC/2in1 最大化、半屏与自由缩放窗口。因此布局判断不能只读取“设备是平板还是电脑”而要以页面真正获得的内容区宽高为依据。二、当前响应式实现分布在两个页面HomePage保存本地宽度State screenWidth: number 360 .onAreaChange((_o, n) { this.screenWidth n.width as number })LearningPage也维护一份相同状态和独立断点函数private gridCols(): string { if (this.screenWidth 840) return 1fr 1fr 1fr 1fr if (this.screenWidth 600) return 1fr 1fr 1fr return 1fr 1fr }这种局部实现短期有效但会产生三个问题页面可能在边界值上使用不同规则每个页面重复处理窗口变化导航和内容布局不知道彼此的窗口等级。三、首页的列数规则存在重复分支HomePage.gridColumns()当前为private gridColumns(): string { if (this.screenWidth 840) return 1fr 1fr 1fr 1fr if (this.screenWidth 600) return 1fr 1fr 1fr return 1fr 1fr 1fr }600vp 以下和 600 到 840vp 都返回三列断点没有改变列数。对于 360vp 手机扣除左右页面边距和两个列间距后每个实验卡片宽度较窄长实验名只能依靠省略。如果产品确实要求手机三列应删除无效分支并明确理由如果目标是手机两列、中宽三列、宽屏四列应让函数真实反映该策略。private columnsFor(sizeClass: WindowSizeClass): number { if (sizeClass WindowSizeClass.EXPANDED) return 4 if (sizeClass WindowSizeClass.MEDIUM) return 3 return 2 }四、一个可以直接复现的 medium 宽度裁切问题首页展示热门实验数量private hotExperiments(): Experiment[] { const count this.screenWidth 600 ? 8 : 6 return this.experiments.slice(0, count) }Grid 高度却固定为.height(172)单个 GridItem 高 82vp行间距 8vp。三种窗口下所需高度如下窗口项目数列数行数所需高度compact若两列62382×3 8×2 262vpmedium83382×3 8×2 262vpexpanded84282×2 8 172vp现有 172vp 只刚好适合 expanded 的两行。尤其在 600 到 840vp 区间8 个项目排成三行却仍只分配两行高度。这不是抽象的适配建议而是可以用 720vp 宽度窗口复现的确定性风险。五、动态列数必须同步动态行数可以根据项目数和列数计算高度private gridHeight( itemCount: number, columns: number, itemHeight: number, rowGap: number ): number { if (itemCount 0 || columns 0) { return 0 } const rows Math.ceil(itemCount / columns) return rows * itemHeight Math.max(0, rows - 1) * rowGap }使用时保证项目数、列数和高度来自同一份计算const items this.hotExperiments() const columns this.columnsFor(this.windowProfile.sizeClass) Grid() { // ForEach(items) } .columnsTemplate(this.columnsTemplate(columns)) .height(this.gridHeight(items.length, columns, 82, 8))如果 Grid 在当前容器中能根据内容自然测量也可以去掉固定高度但必须用真机验证 Scroll 内嵌 Grid 的测量行为不能只删除高度后假设正确。六、建立项目自己的窗口等级断点不是设备型号表而是内容在某个宽度开始需要重排的阈值。本文沿用源码已有的 600 与 840 边界先把它们集中export enum WindowSizeClass { COMPACT compact, MEDIUM medium, EXPANDED expanded } export interface WindowProfile { width: number height: number sizeClass: WindowSizeClass landscape: boolean } export function resolveWindowProfile( width: number, height: number ): WindowProfile { let sizeClass WindowSizeClass.COMPACT if (width 840) { sizeClass WindowSizeClass.EXPANDED } else if (width 600) { sizeClass WindowSizeClass.MEDIUM } return { width, height, sizeClass, landscape: width height } }600 与 840 是本项目的初始断点不应包装成所有 HarmonyOS 应用的通用标准。后续要根据真实内容、字体和窗口测试调整。七、只在根容器采样一次窗口当前 Home 和 Learning 各自监听onAreaChange()。更一致的方案是在主壳获取内容区尺寸再把WindowProfile传给页面State contentWidth: number 360 State contentHeight: number 720 private windowProfile(): WindowProfile { return resolveWindowProfile(this.contentWidth, this.contentHeight) } Stack() { this.MainContent(this.windowProfile()) } .onAreaChange((_oldValue, newValue) { this.contentWidth newValue.width as number this.contentHeight newValue.height as number })页面只消费配置Prop windowProfile: WindowProfile如果某个页面内还有侧栏或内边距应以它自己的可用内容宽度继续细化而不是使用物理屏幕宽度。八、窗口变化要做幂等状态更新onAreaChange可能频繁触发。不要每次都创建大量对象或写入持久化。只在等级、方向或有效尺寸真正变化时更新private updateWindow(width: number, height: number): void { const next resolveWindowProfile(width, height) if ( next.sizeClass this.currentProfile.sizeClass next.landscape this.currentProfile.landscape next.width this.currentProfile.width next.height this.currentProfile.height ) { return } this.currentProfile next }窗口画像属于运行时 UI 状态不需要写入 Preferences。九、compact 布局的目标不是塞下所有内容手机和窄窗口应优先保证核心流程可达底部四标签保持 56vp 稳定高度。首页热门实验使用两列名称允许单行省略。快捷入口保持两列但文字区域必须有layoutWeight(1)。实验室使用单列列表。学习中心使用两列网格。所有长页面使用 Scroll 或 List。窄窗口不要为了展示更多内容把字体、图标和触摸目标继续缩小。十、medium 布局要解决信息密度与高度联动600 到 840vp 常见于平板分屏、折叠屏展开后的窄列或 PC 半屏。建议首页热门实验三列、8 项、三行Grid 高度 262vp。学习分类和工具三列。快捷入口可从两列变为三列或保持两列但限制最大宽度。页面内容区最大宽度可设 720 到 760vp 并居中。实验室仍可单列但行内容限制最大宽度避免描述横向拉得太长。medium 不是“放大后的手机”它通常需要重新计算内容密度。十一、expanded 布局要主动使用宽度840vp 以上的平板横屏和 PC/2in1 窗口可以首页采用左右区域左侧 Banner 与建议右侧热门实验和快捷工具。学习中心四列并把知识分类与工具分区并排。实验室采用左侧筛选列表、右侧实验预览或说明。“我的”页面使用两列卡片区而不是把单列菜单拉满全屏。主内容设置最大宽度超出后留出合理空白。宽屏价值来自并行信息和更少跳转而不是每个卡片横向变宽。十二、统一内容最大宽度PC 最大化时如果所有width(100%)都直接拉满菜单和段落会变得难以扫描。可以建立内容框架private contentMaxWidth(profile: WindowProfile): number | string { if (profile.sizeClass WindowSizeClass.EXPANDED) return 1180 if (profile.sizeClass WindowSizeClass.MEDIUM) return 760 return 100% } Column() { // 页面内容 } .width(this.contentMaxWidth(this.windowProfile)) .alignSelf(ItemAlign.Center)最大宽度值要通过实际页面截图和阅读距离验证不能照搬其他产品。十三、导航形态也应属于窗口画像Index.ets当前所有设备都使用底部 TabsTabs({ barPosition: BarPosition.End, ... }) .barHeight(56)compact 和 medium 可以继续使用底部导航。expanded 窗口则可以切换为左侧导航栏让内容获得更多垂直空间if (profile.sizeClass WindowSizeClass.EXPANDED) { Row() { this.NavigationRail() this.TabContentHost(profile) } } else { this.BottomTabShell(profile) }两种壳必须共享同一个currentIndex与导航契约不能分别维护选中状态。十四、导航切换时要保留业务页面状态从底栏切换到侧栏发生在窗口跨过断点时。若条件分支直接销毁并重建整个页面树用户的滚动位置和筛选条件可能丢失。改造时应验证当前主标签不变。实验室分类筛选不被重置。学习页滚动位置策略明确。正在编辑的笔记不会因为窗口重排丢失草稿。二级页面返回路径不因主壳变化而改变。必要时把关键页面状态提升到主壳或 ViewModel而不是依赖组件实例存活。十五、首页 Banner 固定高度需要字体测试首页 Banner 高度固定 168vp包含标题、副标题和按钮学习页 Banner 固定 132vp。系统字体放大、文本本地化或按钮文字变化后固定高度可能不够。可以使用最小高度与内容撑开Column() { // 标题、副标题、按钮 } .constraintSize({ minHeight: 168 }) .padding({ left: 22, right: 18, top: 20, bottom: 20 })如果视觉必须固定高度则要限制行数并验证最大字体比例不能让文字覆盖按钮。十六、快捷入口不应永久写成四个 RowHomePage当前用四个Row每行两个 QuickAction。宽屏下仍只能两列新增入口还要复制一整段 Row。可以把入口建模为数据并用 Grid 渲染interface QuickActionItem { title: string subtitle: string icon: Resource route: string } Grid() { ForEach(this.quickActions, (item: QuickActionItem) { GridItem() { this.QuickAction(item) } }, (item: QuickActionItem) item.route) } .columnsTemplate(this.quickActionColumns(profile))compact 两列、medium 三列、expanded 四列新增入口无需修改页面骨架。十七、LearningPage 已有好基础但需要去重学习中心的知识分类和学习工具都使用gridCols()可以共享窗口规则。问题是页面自己持有screenWidth断点逻辑与首页重复。改造后两个 Grid 直接消费统一列数private learningColumns(profile: WindowProfile): number { if (profile.sizeClass WindowSizeClass.EXPANDED) return 4 if (profile.sizeClass WindowSizeClass.MEDIUM) return 3 return 2 }卡片高度 98vp 和 88vp 可以保留为稳定格式但要验证长标题、字体放大和英文环境。十八、LabPage 宽屏仍是单列长行实验室当前以 List 展示 56vp 图标、标题、描述、分类和收藏按钮。手机上可扫描PC 宽窗下每行会横向拉得很长信息密度没有提升。expanded 可以采用列表详情布局左栏 360vp分类与实验列表 右栏 自适应实验介绍、参数摘要、开始按钮用户用鼠标选择左侧实验右侧直接预览双击或点击开始进入模拟页。这样利用宽度减少跳转同时保留 compact 下的单列列表。十九、如果暂不做详情栏至少限制列表宽度增量改造可以先让 List 最大宽度 840vp 并居中List() { // 原有 ListItem } .width(100%) .constraintSize({ maxWidth: 840 }) .alignSelf(ItemAlign.Center)这不会增加新交互却能避免描述文字在 PC 上形成过长行。二十、MinePage 在小窗口中存在可达性风险MinePage根节点是固定height(100%)的 Column没有 Scroll。页面包括 88vp 个人区、7 行菜单、分隔线、上下内边距和离线说明卡片。在手机横屏或 PC 窄高窗口中底部内容可能超出可见区域且无法滚动。最小修复是把主体放入 ScrollColumn() { Scroll() { Column() { this.ProfileHeader() this.MenuSection() this.OfflineCard() } .width(100%) } .layoutWeight(1) } .width(100%) .height(100%)所有核心操作在任何窗口高度都必须可达。二十一、MinePage 的 expanded 版本适合两列宽屏下可以把菜单与离线信息分成两列左侧实验记录、统计、收藏、笔记 右侧设置、帮助、关于、离线说明两列卡片各自限制宽度标题和说明保持合理行长。不要在页面区块外再套装饰卡片只让菜单组本身成为清晰容器。二十二、Scroll、List 与 Grid 的职责要分清长顺序记录使用 List便于复用和滚动。固定数量工具卡使用 Grid。由多个不同区块组成的首页和学习页使用 Scroll。不要在外层 Scroll 中再放一个可独立滚动的长 List除非明确处理滚动冲突。Grid 动态列数时要同步处理高度或使用可验证的自然测量。容器选错后适配问题往往表现为滚动区域截断而不是简单的宽度错误。二十三、安全区不能靠设备类型猜Index.ets从 AppStorage 读取statusBarHeight与bottomBarHeight并给 Tabs 添加顶部和底部 padding。安全区策略要与窗口模式一致非沉浸窗口通常已由系统处理部分区域避免重复避让。沉浸式页面需要读取真实避让区。横屏、分屏和窗口化时避让值可能变化。底部页签或工具栏要确保不进入系统手势区。不能因为设备是 tablet 就写死另一组安全区数值。二十四、图片和图标要保持稳定尺寸当前首页实验图标 44vp、实验室列表图标 56vp、底部标签图标 24vp。不同设备上这些固定视觉尺寸可以保留不需要跟随窗口无限放大。响应式不是所有元素等比例缩放而是图标保持清晰尺寸卡片和网格调整排列内容区控制最大宽度必要时增加并行区域。二十五、文字适配要同时检查宽度和高度源码已经大量使用.maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis })这能避免横向溢出但不能解决纵向固定高度。测试时要覆盖系统字体 1.0、1.3、1.75。最长实验名和最长分类名。compact 窗口两列卡片。PC 窗口缩到最小允许宽度。中文与可能的英文资源。重要操作文字不能只剩不可理解的省略号。二十六、2in1 不只有尺寸差异PC/2in1 用户会使用鼠标、触控板和键盘。页面还要补齐可点击行的 hover 与 pressed 反馈。键盘焦点样式。Enter 或 Space 激活主要操作。Tab 顺序符合视觉顺序。收藏星标等图标按钮有明确可访问说明。右键和双击仅在有清晰产品需求时使用。不能只把窗口拉宽就宣称完成 2in1 适配。二十七、不要按设备复制业务逻辑compact、medium 和 expanded 可以有不同页面骨架但实验数据、收藏操作和导航目标必须复用同一业务层。推荐结构ExperimentRepository - CompactLabLayout - MediumLabLayout - ExpandedLabLayout布局组件只负责呈现和事件回调不能各自再实现一遍收藏和路由逻辑。二十八、响应式壳的模块结构模块职责如下WindowProfile统一宽高、方向和窗口等级。NavigationShell选择底部导航或侧边导航。ContentLayout决定网格、分栏、最大宽度和间距。InputPolicy处理触控、鼠标和键盘反馈。业务页面只消费画像不重复定义断点。页面状态在骨架切换时保持稳定。二十九、避免窗口变化时的布局抖动自由缩放会连续触发尺寸变化。若每一个像素都切换复杂页面树会增加重建压力。可以只在跨越断点时切换布局骨架。同一等级内只更新必要的宽高约束。不在build()中创建大型临时数组。ForEach 使用稳定业务键。避免窗口变化时重复读取持久化数据。布局适配与数据加载是两个不同事件不应绑定在一起。三十、断点边界测试必须包含临界值至少测试599vp - compact 600vp - medium 601vp - medium 839vp - medium 840vp - expanded 841vp - expanded如果代码使用而设计文档使用恰好 600vp 与 840vp 会落在不同等级。本文示例统一使用并通过边界测试固定行为。三十一、页面测试矩阵页面compactmediumexpandedIndex底栏可见底栏可见侧栏或受控底栏Home两列、6 项、3 行三列、8 项、3 行四列、8 项、2 行Lab单列列表限宽单列列表详情分栏Learning两列三列四列或分区并排Mine可滚动单列可滚动限宽两列菜单区每个格子都要验证内容、滚动、点击、返回和状态保持。三十二、窗口场景测试手机竖屏冷启动。手机横屏并滚到页面底部。平板竖屏全屏。平板横屏全屏。平板二分屏和三分屏。2in1 从最大化连续缩到最小窗口。跨越 600vp 与 840vp 时保持当前页签。折叠屏展开与折叠时保持筛选状态。系统字体放大后 Banner 和卡片不重叠。键盘 Tab 遍历与 Enter 激活。每次测试记录窗口实际宽高不只记录设备型号。三十三、视觉验收不能只看截图静态截图能发现拉伸、空白和截断但自由窗口还要观察动态过程跨断点时是否闪白。卡片是否突然跳到错误位置。滚动位置是否被重置。点击区域是否与视觉元素分离。页面是否出现短暂空态。连续缩放时是否明显掉帧。必要时录屏并在关键宽度暂停检查。三十四、构建验证完成共享类型、页面参数和条件布局改造后运行项目构建$env:DEVECO_SDK_HOMED:\huawei\DevEco Studio\sdk $env:PATHD:\huawei\DevEco Studio\jbr\bin; $env:PATH D:\huawei\DevEco Studio\tools\hvigor\bin\hvigorw.bat --no-daemon assembleHap构建通过后至少在 phone、tablet 和 2in1 对应模拟器或真机上完成安装、启动、主页面切换、二级页面、返回和卸载烟测。三十五、常见故障排查1. medium 宽度第三行不可见检查项目数、列数、行数与 Grid 高度是否来自同一计算确认没有保留固定 172vp。2. 窗口跨断点后回到首页检查 compact 与 expanded 是否各自维护一份 currentIndex或条件分支是否重建了整个主状态。3. PC 上列表过宽难读检查内容最大宽度、列表详情分栏和段落行长不要只增加左右 padding。4. 横屏底部内容无法操作检查根页面是否缺少 Scroll/List确认底部安全区和窗口高度更新。5. 自由缩放明显卡顿检查是否每次像素变化都重建复杂数据、重新读取存储或生成新数组。骨架切换只应发生在断点变化时。三十六、改造前后对比维度改造前改造后窗口判断页面各自维护宽度根壳统一 WindowProfile断点逻辑重复且首页分支无效compact/medium/expanded 一致首页 Grid列数变化高度固定项目、列数、行数同步计算快捷入口四个固定双列 Row数据驱动响应式 Grid实验室所有窗口单列拉满单列、限宽、列表详情渐进学习中心独立 screenWidth共享列数规则我的页面固定 Column 不可滚动小窗可滚动宽屏两列导航所有设备底栏窄窗底栏宽窗可用侧栏PC 输入只有点击悬停、焦点、键盘激活验证只看设备全屏边界、分屏、自由窗口、字体三十七、最小落地顺序新增WindowProfile与断点边界测试。由 Index 统一采样内容区宽高。修复首页列数和 Grid 动态高度。让 LearningPage 消费统一列数。把 Home 快捷入口改为数据驱动 Grid。给 LabPage 增加内容限宽再逐步做分栏。给 MinePage 增加 Scroll 与 expanded 两列布局。最后切换宽屏导航壳并补鼠标键盘状态。先修复确定性裁切再增加大屏体验风险最小。三十八、验收清单[ ]module.json5的目标设备与发布材料一致。[ ] 页面依据可用窗口宽度而非设备名称重排。[ ] 600vp 和 840vp 边界行为有自动测试。[ ] 首页 compact、medium、expanded 列数符合设计。[ ] 热门实验 Grid 高度与项目数和列数一致。[ ] LearningPage 不再维护重复断点规则。[ ] LabPage 在 PC 宽窗中不会无限拉长单行。[ ] MinePage 在手机横屏和小窗口中可以滚到底部。[ ] expanded 内容有最大宽度或分栏不无限拉伸。[ ] 跨断点后当前页签、筛选和编辑状态不丢失。[ ] 系统字体放大后 Banner、按钮和卡片不重叠。[ ] 底部导航与系统手势区没有遮挡。[ ] 2in1 支持悬停、键盘焦点和 Enter 激活。[ ] 自由缩放时没有明显白屏、跳页或重复加载。[ ] phone、tablet、2in1 完成构建和核心流程烟测。三十九、源码事实与建议实现的边界为了避免把架构建议误读成当前版本已经具备的能力下面把本文引用的源码事实和建议改造逐项分开。左列可直接在one12工程中复核右列是本文给出的后续实现方向。维度当前源码事实本文建议实现目标设备module.json5声明phone、tablet、2in1发布材料和运行验证覆盖三个设备类型及其窗口状态主导航Index.ets始终使用底部Tabs栏高 56vpexpanded 窗口可评估侧边导航但不是当前已实现能力窗口采样HomePage、LearningPage各自通过onAreaChange()保存宽度根壳统一生成WindowProfile业务页面只消费布局能力首页断点840vp 以上四列600vp 以上三列其余仍为三列compact 两列、medium 三列、expanded 四列并统一边界语义热门实验数量宽度大于 600vp 取 8 项否则取 6 项项目数、列数、行数和 Grid 高度由同一次计算产生首页 Grid 高度固定为 172vp根据实际行数计算或在验证测量行为后取消固定高度学习页使用独立screenWidth与两列/三列/四列规则与首页共享断点、间距、最大内容宽度和测试用例实验室页分类横向滚动实验列表始终单列medium 先限宽expanded 再逐步引入列表详情分栏我的页面根节点是不可滚动的Columncompact 和低高度窗口增加滚动expanded 再设计两列菜单区页面状态Index只维护一份currentIndex切换导航骨架时继续复用同一业务状态不复制页面实例鼠标与键盘源码主要定义点击行为2in1 增补悬停、焦点、Enter 激活与可见焦点样式构建和真机结果本文未声称改造方案已经构建或上机验证实施后按文中矩阵执行构建、安装、窗口变化和核心流程烟测这条边界很重要本文对 172vp Grid 的分析来自现有代码可复核WindowProfile、侧边导航、列表详情分栏和键盘策略则是建议方案。读者落地时应按最小改造顺序逐项实现并以构建和设备验证结果为准。四十、总结化学实验室已经声明 phone、tablet 和 2in1也在首页与学习页通过onAreaChange()调整列数。但真正的多设备适配不能停在“宽度大了多放一列”。当前首页 8 个热门实验在 medium 三列下需要三行固定 172vp 高度却只够两行实验室和“我的”页面没有宽屏重排MinePage 缺少滚动小窗口下存在操作不可达风险。增量改造的核心是一份统一WindowProfile。根壳读取实际内容区宽高映射为 compact、medium、expanded导航、网格、列表、最大宽度和输入反馈再消费同一画像。动态列数必须同步动态行数与高度宽屏要增加并行信息或限制内容宽度窄窗要保证滚动和触摸目标。做到这些以后同一套 ArkTS 业务逻辑才能在手机旋转、平板分屏和 PC 自由窗口中保持连续。多设备不是三份页面而是一份稳定业务状态加多种经过验证的布局能力。参考资料Huawei DeveloperHarmonyOS 多设备开发最佳实践https://developer.huawei.com/consumer/cn/best-practices/multidevice/Huawei DeveloperHarmonyOS 设计与多设备场景https://developer.huawei.com/consumer/cn/design/Huawei DeveloperArkUI 概述https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui-overview项目配置entry/src/main/module.json5项目源码entry/src/main/ets/pages/Index.ets项目源码entry/src/main/ets/pages/HomePage.ets项目源码entry/src/main/ets/pages/LabPage.ets项目源码entry/src/main/ets/pages/LearningPage.ets项目源码entry/src/main/ets/pages/MinePage.etsAI 辅助声明本文由 AI 辅助完成源码梳理、结构校对与配图设计技术结论均以文中列出的本地 ArkTS 源码为依据并由作者复核后发布。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询