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

Flutter for OpenHarmony 骨架屏萌系实战指南:给 App 装上软乎乎的 “加载小面包”✨

Flutter for OpenHarmony 骨架屏萌系实战指南:给 App 装上软乎乎的 “加载小面包”✨
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
一、开篇:给鸿蒙 App 加上会呼吸的加载小面包🍞
哈喽~这次我给 Flutter 鸿蒙 App 装上了一个软乎乎的骨架屏!就像给 App 加了块会呼吸的加载小面包,数据加载的时候,页面会显示和真实内容一模一样的占位,用户再也不会盯着空白屏幕发呆啦~
这次的小项目里,我搞定了三件大事:
设计了和页面内容完美匹配的骨架屏,像给 App 拍了张 “素颜照”
实现了骨架屏的显示和隐藏逻辑,加载时乖乖出现,加载完悄悄退场
加了软乎乎的呼吸动画,加载过程看起来像面包在轻轻膨胀,超治愈~
接下来就和我一起看看,怎么给鸿蒙 App 装上这个会呼吸的加载小面包吧~
二、第一步:给页面拍张 “素颜照”,设计匹配的骨架屏🎨
骨架屏的关键就是和真实页面长得像!我给列表页和详情页分别设计了骨架屏,每个占位元素的大小、位置都和真实组件一模一样,用户一眼就能知道页面大概长什么样~
踩过的小坑:
一开始设计的时候,骨架屏和真实页面的间距、大小对不上,加载完成切换的时候会有 “跳一下” 的感觉,像面包突然变形了一样~后来我把真实组件的尺寸直接复制到骨架屏里,连边距、圆角都一模一样,切换的时候就丝滑多啦!
通用骨架屏组件代码

dartimport'package:flutter/material.dart';// 软乎乎的骨架小方块组件classSkeletonBoxextendsStatelessWidget{finaldouble width;finaldouble height;finaldouble radius;constSkeletonBox({super.key,requiredthis.width,requiredthis.height,this.radius=8,});@overrideWidgetbuild(BuildContextcontext){returnContainer(width:width,height:height,decoration:BoxDecoration(color:Colors.grey[200],borderRadius:BorderRadius.circular(radius),),);}}// 列表页骨架屏(和真实列表项长得一模一样)WidgetbuildListSkeleton(int count){returnListView.builder(itemCount:count,itemBuilder:(context,index){returnPadding(padding:constEdgeInsets.symmetric(horizontal:16,vertical:10),child:Row(children:[constSkeletonBox(width:48,height:48,radius:24),// 头像占位constSizedBox(width:12),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constSkeletonBox(width:double.infinity,height:16),// 标题constSizedBox(height:8),constSkeletonBox(width:120,height:12),// 副标题],),),],),);},);}

三、第二步:让骨架屏 “懂礼貌”,显示和隐藏逻辑💡
为了让骨架屏更贴心,我给它加了显示和隐藏逻辑~数据加载的时候,它会乖乖出现;加载完成后,会悄悄退场,不会抢内容的风头~
加载状态控制代码

dartclassCuteListPageextendsStatefulWidget{constCuteListPage({super.key});@overrideState<CuteListPage>createState()=>_CuteListPageState();}class_CuteListPageStateextendsState<CuteListPage>{bool _isLoading=true;List<String>_items=[];@overridevoidinitState(){super.initState();// 模拟网络请求,2秒后加载完成Future.delayed(constDuration(seconds:2),(){setState((){_items=List.generate(10,(i)=>'软乎乎的小面包$i');_isLoading=false;});});}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('软乎乎的列表')),// 用AnimatedSwitcher实现平滑切换body:AnimatedSwitcher(duration:constDuration(milliseconds:300),child:_isLoading?buildListSkeleton(10)// 加载中显示骨架屏:ListView.builder(itemCount:_items.length,itemBuilder:(context,index){returnListTile(leading:constCircleAvatar(child:Icon(Icons.bakery_dining)),title:Text(_items[index]),);},),),);}}

四、第三步:给骨架屏加上 “呼吸动画”,软乎乎超治愈🎀
为了让骨架屏更可爱,我给它加了个呼吸动画!用 shimmer 库实现了渐变闪烁效果,就像面包在烤箱里轻轻膨胀,加载过程看起来超治愈,用户的等待焦虑一下子就没啦~
带呼吸动画的骨架屏代码

dartimport'package:shimmer/shimmer.dart';// 给骨架屏加上呼吸动画WidgetbuildShimmerSkeleton(Widgetchild){returnShimmer.fromColors(baseColor:Colors.grey[200]!,highlightColor:Colors.grey[100]!,period:constDuration(milliseconds:1500),// 呼吸周期child:child,);}// 使用方式:// _isLoading ? buildShimmerSkeleton(buildListSkeleton(10)) : ...

五、第四步:适配鸿蒙细节,让小面包更乖💡
在鸿蒙真机上测试的时候,我发现了几个需要注意的小细节,调整后骨架屏的表现更稳定啦~

  1. 性能优化:给骨架屏 “穿件透气小衣服”
    一开始在鸿蒙设备上,骨架屏动画偶尔会有轻微卡顿,后来我给骨架屏外层包了个RepaintBoundary,减少了不必要的重绘,动画一下子就丝滑多了!
dartWidgetbuildShimmerSkeleton(Widgetchild){returnRepaintBoundary(child:Shimmer.fromColors(baseColor:Colors.grey[200]!,highlightColor:Colors.grey[100]!,period:constDuration(milliseconds:1500),child:child,),);}
  1. 避免快速加载时的 “闪一下”
    有时候网络特别快,数据 100ms 就加载完成了,骨架屏会一闪而过,反而影响体验。我加了个最小显示时间,加载时间小于 300ms 就不显示骨架屏啦~
dart bool _isLoading=true;lateDateTime_loadStartTime;@overridevoidinitState(){super.initState();_loadStartTime=DateTime.now();Future.delayed(constDuration(seconds:2),(){finalloadDuration=DateTime.now().difference(_loadStartTime);if(loadDuration.inMilliseconds<300){// 快速加载,不显示骨架屏setState(()=>_isLoading=false);}else{setState((){_items=List.generate(10,(i)=>'软乎乎的小面包$i');_isLoading=false;});}});}

这是我的运行截图:

六、真机体验:小面包在鸿蒙设备上 “呼吸” 啦🎉
我把这个软乎乎的骨架屏装到鸿蒙真机上试了试,效果超棒:
数据加载的时候,骨架屏会乖乖显示,和真实列表长得一模一样
呼吸动画软乎乎的,像面包在轻轻膨胀,一点都不刺眼
加载完成后,骨架屏会平滑切换成真实内容,一点都不突兀
就算网络慢一点,用户也不会觉得无聊,看着小面包 “呼吸” 超治愈~
七、复盘小技巧:让骨架屏在鸿蒙上更乖💡
折腾下来,我也总结了几个让骨架屏变乖的小技巧:
骨架屏的尺寸、间距一定要和真实页面一模一样,切换才不会跳
用 AnimatedSwitcher 做切换动画,加载完成的过渡会更丝滑
呼吸动画的周期别太短,1.5 秒左右最合适,不会闪眼睛
给骨架屏加上 RepaintBoundary,鸿蒙设备上动画更流畅
真机测试比模拟器靠谱,鸿蒙设备上的动画流畅度只有真机才看得出来~

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

相关文章:

  • 从创意到现实:Cura切片软件如何让3D打印变得简单高效
  • 终极指南:WarcraftHelper如何彻底解锁魔兽争霸3帧率限制实现180fps流畅体验
  • 20.有效的括号
  • 06 链表相交 链表
  • 如何让AI成为你的游戏开发搭档:Godot-MCP完整指南
  • Layui表格导出Excel如何设置导出数据的百分比显示格式
  • 当内存成为枷锁:一位程序员的系统轻盈之旅
  • 基于公开EEG数据的认知流形几何特征研究(世毫九实验室理论研究)
  • LLM 算法岗 | 八股问答()· Transformer 与模型架构原理
  • 终极指南:如何用TV Bro智能电视浏览器彻底改变你的大屏上网体验
  • 免费字幕同步工具:3分钟解决影视字幕不同步问题
  • CAJ转PDF终极指南:免费开源工具解决学术文献兼容难题
  • APK Installer:在Windows上轻松安装安卓应用的终极指南
  • 别再只会调用invoke了!LangChain Model模块的5个高效用法:异步、流式、批处理与缓存配置详解
  • 如何快速掌握高效文件搜索:Linux用户的终极指南
  • HSTracker:macOS炉石传说玩家的终极智能助手与套牌管理器
  • 为什么你的约翰迪尔RX730始终无法接入MCP云平台?深度拆解ISO 11783-12:2024 Annex D中的17项字段映射陷阱
  • 企业级编程语言视觉标识一体化解决方案:专业图标库的技术文档标准化体系
  • 华硕路由器刷Merlin固件全攻略:从编译到高级功能实战
  • JoyCon-Driver终极指南:在Windows上完美使用Switch手柄的完整方案
  • 【OpenClaw企业级智能体实战】第39篇:轻量化AI智能体实战——PicoClaw/ZeroClaw/MimiClaw部署全攻略(Go/Rust/C三语言实现+企业级智算底座)
  • Unity C#入门:第一个C#脚本的创建与挂载
  • U8Cloud 3.5私有化部署详解:从Oracle到DM7/高斯数据库,企业选型与内网离线授权配置
  • CompressO视频压缩工具:3步实现90%体积缩减的终极解决方案
  • Ultralytics YOLOv11多光谱目标检测深度解析:三步实现高效跨通道视觉识别
  • 【OpenClaw从入门到精通】第70篇:为什么它是LLM落地的“最后一公里”?(2026全场景实操指南)
  • 地级市-环境污染处罚数据(2009-2022年)
  • RPG Maker终极解密指南:免费解锁游戏资源的完整解决方案
  • 多语言语义匹配模型架构演进:从1.4GB到352MB的生产级量化优化深度解构
  • VS Code MCP插件生态搭建终极 checklist:含37项必验指标(含TLS双向认证、trace-id透传、workspace trust策略)