HarmonyOS7 页面骨架如何做成组件:ArkUI/ArkTS 实战拆解
文章目录前言为什么这个问题经常被写乱场景资讯列表首屏加载骨架块设计实操步骤先把页面目标想清楚完整示例资讯卡片骨架组件把关键代码一段段拆开容易踩坑的点优化建议骨架组件要轻但不能失真写在最后前言骨架屏不是灰色占位块越多越专业。它应该贴近真实页面结构让用户知道内容正在加载也让页面从加载到完成时不会明显跳动。这篇单独聊通用加载这个场景。重点不是堆 API而是把骨架屏抽成足够小的 ArkUI 构建器让加载态贴近真实页面结构。为什么这个问题经常被写乱页面骨架如何做成组件 这类内容很容易被写成“代码能跑就算讲完了”但对初学者来说这恰恰是最不够的地方。真正让人卡住的往往不是某个组件名记不住而是不知道这段代码为什么要这样拆、状态为什么要这样放、以后需求变化时应该从哪里改。所以这篇文章不只想给你一个能跑的例子更想把背后的判断过程讲清楚。你只要把这个判断过程吃透后面自己改页面、补需求、查问题时心里会稳很多。场景资讯列表首屏加载骨架屏不是把页面涂成一片灰色。它应该告诉用户这里会有标题、这里会有摘要、这里会有列表卡片。资讯、课程、订单、商品列表这类页面如果加载时只放一个转圈用户不知道还要等多久如果骨架结构贴近真实内容等待感会明显降低。我做骨架组件时会控制复杂度。骨架应该是轻量的 UI 片段不应该复制一份完整业务卡片。复制得越像维护成本越高抽得太粗又失去降低跳动的意义。骨架屏不是装饰它是“页面马上会长什么样”的预告。骨架块设计骨架块对应真实内容尺寸建议注意点SkeletonLine标题、摘要12 到 22 vp 高宽度不要全满SkeletonAvatar头像、图标32 到 48 vp圆角贴近真实图形SkeletonCard列表卡片接近真实卡片高度避免加载完成大跳动SkeletonAction按钮32 到 40 vp 高不要太抢眼实操步骤先画真实页面结构再反推骨架块而不是先画灰块。抽出最小单元SkeletonLine复用颜色和圆角。再组合出ArticleSkeletonCard这类业务骨架。加载态和内容态用同一块页面区域切换避免高度差过大。骨架数量与首屏可见内容接近不要一次渲染几十个灰块。接口失败时切到错误态不要让骨架无限显示。先把页面目标想清楚在真正写代码之前先别急着盯着 API。更有用的做法是先想清楚这个页面到底想解决什么问题用户最在意的反馈是什么哪些状态必须一直保持一致。当你先把这条主线想明白再回头看组件和状态设计很多选择都会顺理成章。对小白来说这一步尤其重要因为它能帮你从“照着抄”慢慢过渡到“看得懂、改得动”。完整示例资讯卡片骨架组件interfaceArticleItem{id:numbertitle:stringsummary:stringauthor:string}EntryComponentstruct SkeletonComponentPage{Stateloading:booleantrueStatefailed:booleanfalseprivatearticles:ArticleItem[][{id:1,title:ArkUI 列表加载的几个细节,summary:从骨架屏、空态到错误兜底整理一个更完整的加载体验。,author:编辑部},{id:2,title:HarmonyOS7 页面状态管理实践,summary:用明确状态减少页面闪动和重复判断。,author:技术团队}]BuilderSkeletonLine(widthValue:Length,heightValue:number,radiusValue:number){Blank().width(widthValue).height(heightValue).backgroundColor(#E6EAF0).borderRadius(radiusValue)}BuilderArticleSkeletonCard(){Row({space:12}){this.SkeletonLine(48,48,8)Column({space:10}){this.SkeletonLine(64%,18,4)this.SkeletonLine(92%,14,4)this.SkeletonLine(48%,14,4)}.alignItems(HorizontalAlign.Start).layoutWeight(1)}.padding(14).backgroundColor(#FFFFFF).borderRadius(8)}BuilderArticleCard(item:ArticleItem){Row({space:12}){Text(item.author.substring(0,1)).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#FFFFFF).width(48).height(48).textAlign(TextAlign.Center).backgroundColor(#0A59F7).borderRadius(8)Column({space:6}){Text(item.title).fontSize(16).fontWeight(FontWeight.Medium).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})Text(item.summary).fontSize(13).fontColor(#666666).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})Text(item.author).fontSize(12).fontColor(#999999)}.alignItems(HorizontalAlign.Start).layoutWeight(1)}.padding(14).backgroundColor(#FFFFFF).borderRadius(8)}privatereload(){this.loadingtruethis.failedfalse}build(){Column({space:12}){Row(){Text(加载示例).fontSize(22).fontWeight(FontWeight.Bold)Blank()Button(this.loading?显示内容:显示骨架).onClick(()this.loading!this.loading)}.width(100%)if(this.failed){Column({space:8}){Text(加载失败).fontSize(18).fontWeight(FontWeight.Medium)Text(网络不稳定请稍后重试。).fontSize(13).fontColor(#666666)Button(重试).onClick(()this.reload())}.alignItems(HorizontalAlign.Start).padding(14).backgroundColor(#FFFFFF).borderRadius(8)}elseif(this.loading){this.ArticleSkeletonCard()this.ArticleSkeletonCard()this.ArticleSkeletonCard()}else{ForEach(this.articles,(item:ArticleItem){this.ArticleCard(item)},(item:ArticleItem)item.id.toString())}}.padding(16).height(100%).backgroundColor(#F5F7FA)}}把关键代码一段段拆开SkeletonLine()是最小单元只关心宽、高、圆角。这样标题线、摘要线、头像占位都能复用同一套灰色样式不需要到处复制backgroundColor。ArticleSkeletonCard()的结构和真实ArticleCard()接近左侧头像右侧三行文字。加载完成后高度变化很小页面不会突然跳动。failed和loading分开处理。骨架只能表示“正在加载”不能拿来表示“加载失败”。接口失败后如果骨架一直转用户会以为还在等。容易踩坑的点骨架和真实内容高度差太大加载完成时页面明显跳动。骨架数量过多反而增加首屏渲染压力。把骨架写成完整业务组件的复制版后续维护两套结构。失败后仍显示骨架没有错误兜底。所有灰块宽度都一样看起来不像真实内容。优化建议骨架屏适合超过短暂等待的页面。如果接口通常几十毫秒返回强行闪一下骨架反而打扰用户。可以设置一个很小的延迟策略请求很快完成就不展示骨架请求超过一定时间再展示。颜色上不要用太重的灰尤其是在浅色背景里。骨架应该低调地暗示结构不应该抢走真实内容的位置感。深色模式下也要单独调整骨架色否则灰块可能过亮。骨架组件要轻但不能失真骨架屏的价值在于降低等待感和布局跳动不是复制一套完整业务 UI。灰块要贴近真实内容结构让用户知道页面马上会出现什么但它又不能和真实卡片完全同步维护否则后面改一次业务卡片就要改两份代码。示例先抽SkeletonLine()作为最小单元再组合成ArticleSkeletonCard()。这样颜色、圆角和尺寸可以复用资讯卡片的左图右文结构也能保留下来加载完成时页面不会明显跳动。写在最后失败态要和加载态分开。骨架只表示“正在加载”接口失败后应该切到错误提示和重试入口。如果骨架无限显示用户会以为还在等待实际已经没有下一步了。

相关新闻

Java项目第三方依赖安全扫描实战:Dependency-Check工具详解与CI/CD集成

Java项目第三方依赖安全扫描实战:Dependency-Check工具详解与CI/CD集成

1. 项目概述:为什么你的Java项目需要一个“安全门卫” 最近在给一个老项目做安全审计,发现一个挺普遍但容易被忽视的问题:项目里用到的第三方库,版本老得能进博物馆了,里面藏着好几个高危漏洞,而团队里居然…

2026/10/7 15:52:59 阅读更多 →
Claude Code CLI:将AI代码助手融入命令行工作流

Claude Code CLI:将AI代码助手融入命令行工作流

1. 项目概述:当AI代码助手遇上命令行最近在折腾一个老项目的代码重构,面对几千个文件,想快速找出所有使用了某个特定废弃API的地方。第一反应是打开终端,敲下熟悉的grep -r “old_function_name” .。但转念一想,这次要…

2026/10/14 16:35:57 阅读更多 →
55-工厂6S落地工具体系化构建研究:全流程五大阶段与七大核心工具 | 杨逢昌

55-工厂6S落地工具体系化构建研究:全流程五大阶段与七大核心工具 | 杨逢昌

《6S管理实战专栏》 三环实战篇(第55篇) 杨逢昌使命: 用6S的力量,让10万名朋友实现高效愉悦的生活与工作。摘要6S 管理在制造企业应用广泛,但普遍存在 "从零摸索、工具零散、不成体系" 的问题,严…

2026/9/28 23:38:52 阅读更多 →

最新新闻

电力行业国产化ERP成本管理方案:从核算到管控的落地实践

电力行业国产化ERP成本管理方案:从核算到管控的落地实践

电力行业的ERP建设,一直是个“看着标准化、落地极复杂”的领域。特别是成本管理模块,发、输、配、售四个环节的业务逻辑差异巨大,资产密集程度在全部工业门类里都排在最前列,加上电价监管对成本分摊的精细化要求,传统通…

2026/10/15 23:01:26 阅读更多 →
Superpowers:AI原生开发的IDE认知增强协议

Superpowers:AI原生开发的IDE认知增强协议

1. 项目概述:Superpowers 不是超能力,而是开发者工具链的“认知增强层”你搜“superpowers”时,第一反应可能是漫威电影或DC宇宙——但最近半年,在开发者社区、技术论坛和GitHub trending榜单上,“Superpowers”这个词…

2026/10/15 23:01:26 阅读更多 →
MATLAB间断有限元声波模拟:从原理到可调试DG实现

MATLAB间断有限元声波模拟:从原理到可调试DG实现

简介:本资源是一套基于Matlab实现二维声波方程数值求解的教学实践代码包,面向计算数学、声学仿真及偏微分方程数值方法方向的高年级本科生与研究生,聚焦间断有限元(DG)方法在波动问题中的应用。资源采用线性基函数构建…

2026/10/15 23:01:26 阅读更多 →
Codex超级能力配置:用AGENTS.md规则驱动AI工程化协作

Codex超级能力配置:用AGENTS.md规则驱动AI工程化协作

Codex 的默认能力其实一直被严重低估,很多人用了一两天就放弃,说“它就是个高级补全工具”。我一开始也这么觉得,直到花了整个周末把超级能力(superpowers)配置方案完整地跑了一遍,才发现问题根本不在 Code…

2026/10/15 23:01:26 阅读更多 →
SAP ECC 6.0 安装实战:跨层协同与硬性配置指南

SAP ECC 6.0 安装实战:跨层协同与硬性配置指南

简介:本资源是一份详实的SAP ECC 6.0个人笔记本环境安装操作手册,面向SAP初学者、BASIS入门人员及希望在本地搭建学习系统的IT从业者,解决ECC6.0部署复杂、依赖繁多、易因配置疏漏导致失败等核心痛点。文档为单个Word文件(.doc&am…

2026/10/15 23:01:26 阅读更多 →
从波形到断言:用脚本把实验参考答案变成可验证过程

从波形到断言:用脚本把实验参考答案变成可验证过程

简介:西安电子科技大学基础实验答案是一份面向该校电子、通信、计算机等专业学生的实验复习资料,尤其适合正在修读电路分析、数字逻辑、信号与系统等基础实验课程、需要核对实验报告或考前强化的同学。压缩包内仅包含一个Word文档,大小约669K…

2026/10/15 23:00:25 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →