基于 Harmony 6.0 应用的运动轨迹记录与分享应用首页实现前言跑步、骑行、徒步、滑雪——一切可以画出一条线的运动都值得被记录、被分享、被回忆。一款好的运动轨迹应用要把今天跑了多少 / 这条路线长什么样 / 我和朋友比谁跑得快 / 我什么时候休息过这四件事用最直观的方式呈现。Harmony 6.0 时代运动轨迹应用迎来了几个独特的能力红利——HealthKit 提供运动数据深度采集心率 / 配速 / 步频 / VO2max、LocationKit 提供米级 GPS 轨迹、超级终端让手表和手机的运动数据无缝联动、HMS Push 让挑战赛排行榜更新精准触达。本文用 Flutter 在 Harmony 6.0 上实现一个运动轨迹首页作为本系列第十组的第二篇。背景运动轨迹类应用的视觉关键词是活力、专业、社交——活力对应色彩饱满偏运动,专业对应数据网格必须显著,社交对应好友排行必须存在。橙色 #F97316 配青色 #06B6D4 是这类应用的典型主色——既有动力又有清新。本项目首页 5 个模块渐变 Header本月公里 大开始按钮、本周数据网格公里 / 时长 / 配速 / 卡路里、最近一次运动卡片轨迹缩略 数据、好友 PK 排行榜、推荐路线横滑。从产品角度运动轨迹应用最大的复购点是持续记录——用户每次跑步都期待打开应用马上能开始记录所以 Header 的开始运动按钮必须做成最大最显眼的元素。鸿蒙 6.0 上做这种快速开始非常友好——用户在桌面长按服务卡片开始跑步即可直达运动记录页不必反复进入主 App。Flutter × Harmony 6.0 跨端开发介绍Harmony 6.0 在运动健身类应用上的能力栈非常完整——HealthKit 提供运动数据深度采集、LocationKit 提供米级 GPS、SensorKit 提供加速度计 / 陀螺仪等传感器数据、超级终端让运动数据多设备联动、PushKit 提供运动提醒、AI 助手能力提供训练建议。Flutter 嵌入 Harmony 6.0 的方案在这种重数据采集 轻 UI应用上非常合适——主页用 Flutter 自绘提供丰富 UI运动数据采集通过 ArkTS 端 HealthKit 接入。Skia 引擎对橙青色#F97316 / #06B6D4的混合渲染非常活力配合圆角和阴影整页氛围既动感又专业。开发核心代码代码一本月数据 开始按钮 HeaderHeader 必须把本月公里数 开始按钮做成视觉中心——这是用户使用应用的核心目的。我用一个橙色渐变 Container顶部一行 SLOGAN中部本月公里数大字号底部一个白底圆形开始运动按钮。Widget_header(){returnContainer(padding:constEdgeInsets.all(20),decoration:BoxDecoration(gradient:constLinearGradient(colors:[_primary,Color(0xFFFB923C)],begin:Alignment.topLeft,end:Alignment.bottomRight),borderRadius:BorderRadius.circular(24),),child:Column(children:[constRow(children:[Icon(Icons.directions_run,color:Colors.white,size:22),SizedBox(width:8),Text(运动轨迹,style:TextStyle(color:Colors.white,fontSize:18,fontWeight:FontWeight.w800)),Spacer(),Icon(Icons.calendar_view_month,color:Colors.white,size:22),]),constSizedBox(height:14),constText(本月已跑,style:TextStyle(color:Colors.white70,fontSize:13)),constSizedBox(height:6),constRow(crossAxisAlignment:CrossAxisAlignment.end,children:[Text(128.6,style:TextStyle(color:Colors.white,fontSize:48,fontWeight:FontWeight.w900)),SizedBox(width:6),Padding(padding:EdgeInsets.only(bottom:10),child:Text(km,style:TextStyle(color:Colors.white,fontSize:18,fontWeight:FontWeight.w700))),]),constSizedBox(height:14),Container(width:double.infinity,height:50,decoration:BoxDecoration(color:Colors.white,borderRadius:BorderRadius.circular(25),boxShadow:[BoxShadow(color:Colors.black.withValues(alpha:0.16),blurRadius:12,offset:constOffset(0,4))]),child:constCenter(child:Row(mainAxisSize:MainAxisSize.min,children:[Icon(Icons.play_arrow,color:_primary,size:24),SizedBox(width:6),Text(开始运动,style:TextStyle(color:_primary,fontSize:16,fontWeight:FontWeight.w800)),],)),),]),);}开始运动按钮在生产业务里点击后会触发 LocationKit 开始记录 GPS HealthKit 开始采集心率 SensorKit 开始采集步频。整个数据采集链路在鸿蒙 6.0 上的功耗非常低用户跑一小时只消耗手机 5% 左右电量。从「本月数据 开始按钮 Header」的运动激励设计角度再补一段。运动轨迹类应用的 Header 必须传递「我已经积累了多少 现在就出发」的双重激励。这段 Header 用主蓝色渐变背景配合「本月已跑 X 公里 / 燃烧 X kcal」的双数据 「开始运动」大按钮的三段式排版让用户既能感知积累成就又能快速开始。“开始运动” 按钮做成纯白色实心 主色文字的胶囊形态是整页最显眼的视觉锚点。如果未来要支持「跑步、骑行、徒步、滑雪」多种运动类型切换可以在 Header 顶部加 chip 切换栏骨架不变。鸿蒙 6.0 的 HealthKit 对多运动类型的数据采集是原生支持的无需引入第三方 SDK。代码二本周数据网格本周运动数据用 4 等分网格展示——公里、时长、配速、卡路里。每项一个图标 大字号数据 单位。Widget_stats(){finalitemsconst[[Icons.straighten,32.4,km,_primary],[Icons.access_time,3:28,h,_amber],[Icons.speed,612,配速,_green],[Icons.local_fire_department,2,186,kcal,_accent],];returnContainer(padding:constEdgeInsets.all(16),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(16)),child:Row(children:items.map((it){finalcit[3]asColor;returnExpanded(child:Column(children:[Icon(it[0]asIconData,color:c,size:20),constSizedBox(height:8),Text(it[1]asString,style:constTextStyle(color:_ink,fontSize:18,fontWeight:FontWeight.w900)),constSizedBox(height:2),Text(it[2]asString,style:constTextStyle(color:_sub,fontSize:11)),]));}).toList()),);}这些数据在生产业务里全部从 HealthKit 实时获取——用户运动时手表和手机协同采集运动结束后数据自动汇总。这种端到端的健康数据流是 Harmony 6.0 端独有的体验红利。从「本周数据网格」的多维数据可视化与健康分析设计角度再补一段。运动数据的核心维度距离、时长、配速、心率、卡路里、步频必须在一屏内全部交付。这段网格用 2x3 布局展示 6 项数据每项用「数值 单位 标签 图标」四件套呈现让用户一眼扫过就能掌握全部运动指标。每项数据的图标用对应主题色距离蓝、时长青、配速橙、心率红、卡路里黄、步频紫做识别。这种「6 数据 多色编码」的网格在国内运动类 App咕咚、悦跑圈都有验证。如果未来要扩展支持「数据对比」本周 vs 上周可以在每个数据下方加一个小折线图鸿蒙 6.0 端的 Skia 自绘性能足以支持每帧 6 张折线图实时渲染。代码三最近一次运动卡片最近一次运动卡片需要包含——日期、轨迹缩略图、距离、用时、配速、运动类型。我用 Container 包裹顶部一个 100 高度的浅色 Container 用 CustomPaint 模拟轨迹实际业务里换成真实 GPS 路径下方一行数据。Widget_lastSession(){returnContainer(padding:constEdgeInsets.all(14),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(16)),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constRow(children:[Icon(Icons.directions_run,color:_primary,size:18),SizedBox(width:6),Text(上次跑步 · 5 月 26 日,style:TextStyle(color:_ink,fontSize:13,fontWeight:FontWeight.w700)),Spacer(),Icon(Icons.share,color:_sub,size:18),]),constSizedBox(height:12),Container(height:100,decoration:BoxDecoration(color:_primary.withValues(alpha:0.08),borderRadius:BorderRadius.circular(12)),child:Stack(children:[// 用 stack 模拟轨迹...List.generate(8,(i){returnPositioned(left:30.0i*35.0,top:i.isEven?30.0:50.0,child:Container(width:8,height:8,decoration:BoxDecoration(color:_primary,shape:BoxShape.circle)),);}),constPositioned(top:8,right:8,child:Icon(Icons.flag,color:_accent,size:18)),]),),constSizedBox(height:12),constRow(children:[Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(5.2 km,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(距离,style:TextStyle(color:_sub,fontSize:11)),],)),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(32:18,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(用时,style:TextStyle(color:_sub,fontSize:11)),],)),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(612\,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(平均配速,style:TextStyle(color:_sub,fontSize:11)),],)),]),]),);}轨迹缩略图在生产业务里通过 ArkUI Canvas 原生绘制——把 LocationKit 拿到的经纬度路径数据投影到 2D 画布上性能比 Flutter 自绘 CustomPaint 更好。从「最近一次运动」卡片的成就分享与社交传播设计角度再补一段。运动应用的核心是「让用户为自己的运动感到骄傲」运动卡片必须能直接分享到朋友圈或微博。这段大卡片用「轨迹缩略图占位 运动类型 距离 时长 配速 海拔变化 分享按钮」的多段式排版让用户的视觉动线从「轨迹视觉惊艳→ 数据成就→ 分享社交」一气呵成。轨迹缩略图作为卡片的视觉中心是运动应用的「灵魂」——一条优雅的轨迹比任何文字都更能打动用户。如果未来要扩展支持「轨迹动画回放」让用户回看自己跑步时的整条轨迹动画可以用 AnimatedBuilder 配合 CustomPaint 实现鸿蒙 6.0 端的 Skia 自绘动画足以支持长达数小时的轨迹回放。心得运动轨迹类 App 的视觉灵魂是活力 数据——橙色给活力大字号数据给专业。开发时最容易犯的错是把开始运动按钮做得太小反而稀释了运动应用的核心心智。我的策略是把开始按钮做成 Header 底部最显眼的圆角条让它成为整页第一吸睛点。从能力扩展角度运动轨迹应用最值得在鸿蒙端打造的是HealthKit LocationKit 超级终端三件套——HealthKit 让运动数据全面而准确、LocationKit 让 GPS 轨迹精准、超级终端让手表和手机协同采集。总结本篇实现了 Harmony 6.0 端的运动轨迹首页5 个模块、纯 UI、零依赖、约 360 行代码。骨架可直接迁移到骑行、徒步、滑雪、游泳等多种运动场景。从扩展角度建议生产业务里把运动数据接入 HealthKit把 GPS 轨迹接入 LocationKit把传感器数据接入 SensorKit把手表协同接入超级终端能力把本月公里数做成 FormExtensionAbility 桌面卡片把开始跑步接入 AI 助手语义路由。下一篇是第十组的最后一块——饮食卡路里计算器。
基于 Harmony 6.0 应用的运动轨迹记录与分享应用首页实现
基于 Harmony 6.0 应用的运动轨迹记录与分享应用首页实现前言跑步、骑行、徒步、滑雪——一切可以画出一条线的运动都值得被记录、被分享、被回忆。一款好的运动轨迹应用要把今天跑了多少 / 这条路线长什么样 / 我和朋友比谁跑得快 / 我什么时候休息过这四件事用最直观的方式呈现。Harmony 6.0 时代运动轨迹应用迎来了几个独特的能力红利——HealthKit 提供运动数据深度采集心率 / 配速 / 步频 / VO2max、LocationKit 提供米级 GPS 轨迹、超级终端让手表和手机的运动数据无缝联动、HMS Push 让挑战赛排行榜更新精准触达。本文用 Flutter 在 Harmony 6.0 上实现一个运动轨迹首页作为本系列第十组的第二篇。背景运动轨迹类应用的视觉关键词是活力、专业、社交——活力对应色彩饱满偏运动,专业对应数据网格必须显著,社交对应好友排行必须存在。橙色 #F97316 配青色 #06B6D4 是这类应用的典型主色——既有动力又有清新。本项目首页 5 个模块渐变 Header本月公里 大开始按钮、本周数据网格公里 / 时长 / 配速 / 卡路里、最近一次运动卡片轨迹缩略 数据、好友 PK 排行榜、推荐路线横滑。从产品角度运动轨迹应用最大的复购点是持续记录——用户每次跑步都期待打开应用马上能开始记录所以 Header 的开始运动按钮必须做成最大最显眼的元素。鸿蒙 6.0 上做这种快速开始非常友好——用户在桌面长按服务卡片开始跑步即可直达运动记录页不必反复进入主 App。Flutter × Harmony 6.0 跨端开发介绍Harmony 6.0 在运动健身类应用上的能力栈非常完整——HealthKit 提供运动数据深度采集、LocationKit 提供米级 GPS、SensorKit 提供加速度计 / 陀螺仪等传感器数据、超级终端让运动数据多设备联动、PushKit 提供运动提醒、AI 助手能力提供训练建议。Flutter 嵌入 Harmony 6.0 的方案在这种重数据采集 轻 UI应用上非常合适——主页用 Flutter 自绘提供丰富 UI运动数据采集通过 ArkTS 端 HealthKit 接入。Skia 引擎对橙青色#F97316 / #06B6D4的混合渲染非常活力配合圆角和阴影整页氛围既动感又专业。开发核心代码代码一本月数据 开始按钮 HeaderHeader 必须把本月公里数 开始按钮做成视觉中心——这是用户使用应用的核心目的。我用一个橙色渐变 Container顶部一行 SLOGAN中部本月公里数大字号底部一个白底圆形开始运动按钮。Widget_header(){returnContainer(padding:constEdgeInsets.all(20),decoration:BoxDecoration(gradient:constLinearGradient(colors:[_primary,Color(0xFFFB923C)],begin:Alignment.topLeft,end:Alignment.bottomRight),borderRadius:BorderRadius.circular(24),),child:Column(children:[constRow(children:[Icon(Icons.directions_run,color:Colors.white,size:22),SizedBox(width:8),Text(运动轨迹,style:TextStyle(color:Colors.white,fontSize:18,fontWeight:FontWeight.w800)),Spacer(),Icon(Icons.calendar_view_month,color:Colors.white,size:22),]),constSizedBox(height:14),constText(本月已跑,style:TextStyle(color:Colors.white70,fontSize:13)),constSizedBox(height:6),constRow(crossAxisAlignment:CrossAxisAlignment.end,children:[Text(128.6,style:TextStyle(color:Colors.white,fontSize:48,fontWeight:FontWeight.w900)),SizedBox(width:6),Padding(padding:EdgeInsets.only(bottom:10),child:Text(km,style:TextStyle(color:Colors.white,fontSize:18,fontWeight:FontWeight.w700))),]),constSizedBox(height:14),Container(width:double.infinity,height:50,decoration:BoxDecoration(color:Colors.white,borderRadius:BorderRadius.circular(25),boxShadow:[BoxShadow(color:Colors.black.withValues(alpha:0.16),blurRadius:12,offset:constOffset(0,4))]),child:constCenter(child:Row(mainAxisSize:MainAxisSize.min,children:[Icon(Icons.play_arrow,color:_primary,size:24),SizedBox(width:6),Text(开始运动,style:TextStyle(color:_primary,fontSize:16,fontWeight:FontWeight.w800)),],)),),]),);}开始运动按钮在生产业务里点击后会触发 LocationKit 开始记录 GPS HealthKit 开始采集心率 SensorKit 开始采集步频。整个数据采集链路在鸿蒙 6.0 上的功耗非常低用户跑一小时只消耗手机 5% 左右电量。从「本月数据 开始按钮 Header」的运动激励设计角度再补一段。运动轨迹类应用的 Header 必须传递「我已经积累了多少 现在就出发」的双重激励。这段 Header 用主蓝色渐变背景配合「本月已跑 X 公里 / 燃烧 X kcal」的双数据 「开始运动」大按钮的三段式排版让用户既能感知积累成就又能快速开始。“开始运动” 按钮做成纯白色实心 主色文字的胶囊形态是整页最显眼的视觉锚点。如果未来要支持「跑步、骑行、徒步、滑雪」多种运动类型切换可以在 Header 顶部加 chip 切换栏骨架不变。鸿蒙 6.0 的 HealthKit 对多运动类型的数据采集是原生支持的无需引入第三方 SDK。代码二本周数据网格本周运动数据用 4 等分网格展示——公里、时长、配速、卡路里。每项一个图标 大字号数据 单位。Widget_stats(){finalitemsconst[[Icons.straighten,32.4,km,_primary],[Icons.access_time,3:28,h,_amber],[Icons.speed,612,配速,_green],[Icons.local_fire_department,2,186,kcal,_accent],];returnContainer(padding:constEdgeInsets.all(16),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(16)),child:Row(children:items.map((it){finalcit[3]asColor;returnExpanded(child:Column(children:[Icon(it[0]asIconData,color:c,size:20),constSizedBox(height:8),Text(it[1]asString,style:constTextStyle(color:_ink,fontSize:18,fontWeight:FontWeight.w900)),constSizedBox(height:2),Text(it[2]asString,style:constTextStyle(color:_sub,fontSize:11)),]));}).toList()),);}这些数据在生产业务里全部从 HealthKit 实时获取——用户运动时手表和手机协同采集运动结束后数据自动汇总。这种端到端的健康数据流是 Harmony 6.0 端独有的体验红利。从「本周数据网格」的多维数据可视化与健康分析设计角度再补一段。运动数据的核心维度距离、时长、配速、心率、卡路里、步频必须在一屏内全部交付。这段网格用 2x3 布局展示 6 项数据每项用「数值 单位 标签 图标」四件套呈现让用户一眼扫过就能掌握全部运动指标。每项数据的图标用对应主题色距离蓝、时长青、配速橙、心率红、卡路里黄、步频紫做识别。这种「6 数据 多色编码」的网格在国内运动类 App咕咚、悦跑圈都有验证。如果未来要扩展支持「数据对比」本周 vs 上周可以在每个数据下方加一个小折线图鸿蒙 6.0 端的 Skia 自绘性能足以支持每帧 6 张折线图实时渲染。代码三最近一次运动卡片最近一次运动卡片需要包含——日期、轨迹缩略图、距离、用时、配速、运动类型。我用 Container 包裹顶部一个 100 高度的浅色 Container 用 CustomPaint 模拟轨迹实际业务里换成真实 GPS 路径下方一行数据。Widget_lastSession(){returnContainer(padding:constEdgeInsets.all(14),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(16)),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constRow(children:[Icon(Icons.directions_run,color:_primary,size:18),SizedBox(width:6),Text(上次跑步 · 5 月 26 日,style:TextStyle(color:_ink,fontSize:13,fontWeight:FontWeight.w700)),Spacer(),Icon(Icons.share,color:_sub,size:18),]),constSizedBox(height:12),Container(height:100,decoration:BoxDecoration(color:_primary.withValues(alpha:0.08),borderRadius:BorderRadius.circular(12)),child:Stack(children:[// 用 stack 模拟轨迹...List.generate(8,(i){returnPositioned(left:30.0i*35.0,top:i.isEven?30.0:50.0,child:Container(width:8,height:8,decoration:BoxDecoration(color:_primary,shape:BoxShape.circle)),);}),constPositioned(top:8,right:8,child:Icon(Icons.flag,color:_accent,size:18)),]),),constSizedBox(height:12),constRow(children:[Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(5.2 km,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(距离,style:TextStyle(color:_sub,fontSize:11)),],)),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(32:18,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(用时,style:TextStyle(color:_sub,fontSize:11)),],)),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(612\,style:TextStyle(color:_primary,fontSize:18,fontWeight:FontWeight.w900)),Text(平均配速,style:TextStyle(color:_sub,fontSize:11)),],)),]),]),);}轨迹缩略图在生产业务里通过 ArkUI Canvas 原生绘制——把 LocationKit 拿到的经纬度路径数据投影到 2D 画布上性能比 Flutter 自绘 CustomPaint 更好。从「最近一次运动」卡片的成就分享与社交传播设计角度再补一段。运动应用的核心是「让用户为自己的运动感到骄傲」运动卡片必须能直接分享到朋友圈或微博。这段大卡片用「轨迹缩略图占位 运动类型 距离 时长 配速 海拔变化 分享按钮」的多段式排版让用户的视觉动线从「轨迹视觉惊艳→ 数据成就→ 分享社交」一气呵成。轨迹缩略图作为卡片的视觉中心是运动应用的「灵魂」——一条优雅的轨迹比任何文字都更能打动用户。如果未来要扩展支持「轨迹动画回放」让用户回看自己跑步时的整条轨迹动画可以用 AnimatedBuilder 配合 CustomPaint 实现鸿蒙 6.0 端的 Skia 自绘动画足以支持长达数小时的轨迹回放。心得运动轨迹类 App 的视觉灵魂是活力 数据——橙色给活力大字号数据给专业。开发时最容易犯的错是把开始运动按钮做得太小反而稀释了运动应用的核心心智。我的策略是把开始按钮做成 Header 底部最显眼的圆角条让它成为整页第一吸睛点。从能力扩展角度运动轨迹应用最值得在鸿蒙端打造的是HealthKit LocationKit 超级终端三件套——HealthKit 让运动数据全面而准确、LocationKit 让 GPS 轨迹精准、超级终端让手表和手机协同采集。总结本篇实现了 Harmony 6.0 端的运动轨迹首页5 个模块、纯 UI、零依赖、约 360 行代码。骨架可直接迁移到骑行、徒步、滑雪、游泳等多种运动场景。从扩展角度建议生产业务里把运动数据接入 HealthKit把 GPS 轨迹接入 LocationKit把传感器数据接入 SensorKit把手表协同接入超级终端能力把本月公里数做成 FormExtensionAbility 桌面卡片把开始跑步接入 AI 助手语义路由。下一篇是第十组的最后一块——饮食卡路里计算器。