基于 Harmony 6.0 应用的课程表与成绩计算器应用首页实现
前言
课程表是大学生最高频使用的工具之一——每天打开手机看"下一节课在哪、几点开始、教室在哪"。配合成绩计算器和 GPA 预估,这类应用几乎是每个学生的桌面必备。Harmony 6.0 时代,课程表应用迎来了几个独特的能力红利——分布式数据让课表多端同步、PushKit 让"下节课 10 分钟后开始"精准提醒、桌面服务卡片让"今日课程"在桌面常驻、HMS Account 让学籍信息一键导入。本文用 Flutter 在 Harmony 6.0 上实现一个课程表首页,作为本系列第十三组的收官。
背景
工具类应用的视觉关键词是"清晰、紧凑、信息密度大"——清晰对应"今日课程必须显著",紧凑对应"一周课表用网格密集呈现",信息密度大对应"GPA / 学分 / 成绩等数据在 Header 充分展示"。靛蓝色 #4F46E5 配橙色 #F97316 是这类应用的合适主色。本项目首页 5 个模块:渐变 Header(GPA + 已修学分)、今日课程列表、本周课表网格(5x6 时间×星期)、成绩计算器入口、考试倒计时列表。
Flutter × Harmony 6.0 跨端开发介绍
Harmony 6.0 在校园工具类应用上的能力栈完整——HMS Account 提供学籍认证、分布式数据让课表多端同步、PushKit 提供精准课前提醒、AI 助手能力提供学业建议、超级终端让课表可在车机上看(去教室路上)。Skia 引擎对靛蓝橙色(#4F46E5 / #F97316)的混合渲染清爽专业。
开发核心代码
代码一:GPA + 学分 Header
Header 必须把"GPA + 已修学分"做成视觉中心。我用一个靛蓝渐变 Container,顶部"清华大学 · 计算机系",中部 GPA 大字号 + 学分进度条。
Widget_header(){returnContainer(padding:constEdgeInsets.all(20),decoration:BoxDecoration(gradient:constLinearGradient(colors:[_primary,Color(0xFF3730A3)],begin:Alignment.topLeft,end:Alignment.bottomRight),borderRadius:BorderRadius.circular(24),),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constRow(children:[Icon(Icons.school,color:Colors.white,size:22),SizedBox(width:8),Text('清华大学 · 计算机系',style:TextStyle(color:Colors.white,fontSize:14,fontWeight:FontWeight.w700)),Spacer(),Icon(Icons.calendar_today,color:Colors.white,size:22),]),constSizedBox(height:14),constRow(children:[Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text('GPA',style:TextStyle(color:Colors.white70,fontSize:12)),SizedBox(height:4),Text('3.86',style:TextStyle(color:Colors.white,fontSize:38,fontWeight:FontWeight.w900)),Text('全班 #6 / 80',style:TextStyle(color:Colors.white70,fontSize:11)),],)),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text('已修学分',style:TextStyle(color:Colors.white70,fontSize:12)),SizedBox(height:4),Text('86 / 138',style:TextStyle(color:Colors.white,fontSize:22,fontWeight:FontWeight.w900)),SizedBox(height:8),],)),]),constSizedBox(height:4),ClipRRect(borderRadius:BorderRadius.circular(3),child:constLinearProgressIndicator(value:0.62,minHeight:6,backgroundColor:Colors.white24,valueColor:AlwaysStoppedAnimation(Colors.white),),),],),);}GPA 数据通过 HMS Account 的学籍认证后从教务系统拉取,学分数据通过分布式数据对象多端同步。
从「GPA + 学分 Header」的学业表现可视化与目标驱动设计角度再补一段。课程表类应用的 Header 必须把「我现在的学业表现 + 还差多少」做成视觉中心。这段 Header 用主蓝色到深紫的渐变背景,配合 GPA + 学分双数据 + 「本学期目标」的副信息的多段式排版,让用户每天打开应用都能看到自己的进度。GPA 数字用 32 号粗体白字,是整页最大的视觉锚点。如果未来要扩展支持「按学院 / 班级排名」(让用户看到自己在班级里的相对位置),可以在 Header 加排名 chip,配合 HMS Account 的学籍体系实现安全合规的排名展示。
代码二:今日课程列表
今日课程每条包含——时间段、课名、教室、老师、签到状态。我用左边竖色条 + 主体内容的卡片样式。
Widget_todayClass(Map<String,dynamic>c){finalcolor=c['color']asColor;returnContainer(margin:constEdgeInsets.only(bottom:10),padding:constEdgeInsets.all(14),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(14),border:Border(left:BorderSide(color:color,width:4))),child:Row(children:[Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(c['time']asString,style:TextStyle(color:color,fontSize:14,fontWeight:FontWeight.w800)),constSizedBox(height:2),Text(c['period']asString,style:constTextStyle(color:_sub,fontSize:11)),]),constSizedBox(width:16),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(c['name']asString,style:constTextStyle(color:_ink,fontSize:14,fontWeight:FontWeight.w700)),constSizedBox(height:4),Row(children:[constIcon(Icons.location_on,color:_sub,size:12),Text(c['room']asString,style:constTextStyle(color:_sub,fontSize:11)),constSizedBox(width:8),Text(c['teacher']asString,style:constTextStyle(color:_sub,fontSize:11)),]),],)),Container(padding:constEdgeInsets.symmetric(horizontal:8,vertical:3),decoration:BoxDecoration(color:color.withValues(alpha:0.16),borderRadius:BorderRadius.circular(6)),child:Text(c['status']asString,style:TextStyle(color:color,fontSize:11,fontWeight:FontWeight.w700)),),]),);}每节课通过 PushKit 在课前 10 分钟自动推送提醒,让学生不会忘记。
从「今日课程列表」的时间感知与课程信息聚合设计角度再补一段。今日课程列表是大学生最常打开的核心信息位——必须做到「一眼看完今天有几节课、几点几分、在哪上、是否到点」。这段列表用「时间槽 + 课程名 + 教室 + 老师 + 状态 chip」五段信息塞在每条卡片里。当前正在上的课用主色高亮 + 「正在上课」chip,下一节课用普通色调,已结束的课用灰色 + 删除线。这种「状态可视化」让学生一眼识别「现在该去哪上课」。如果未来要扩展支持「调课 / 停课实时同步」,接入分布式数据对象 + PushKit 让课表变化秒级推送。
代码三:本周课表网格
本周课表用 5x6 的网格表示(5 节课 × 6 个上课日),每节课用一个色块 + 课名。
Widget_weekGrid(){returnContainer(padding:constEdgeInsets.all(14),decoration:BoxDecoration(color:_card,borderRadius:BorderRadius.circular(16)),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[constRow(children:[Text('本周课表',style:TextStyle(color:_ink,fontSize:14,fontWeight:FontWeight.w700)),Spacer(),Text('完整周视图',style:TextStyle(color:_primary,fontSize:12)),]),constSizedBox(height:12),Row(children:const[SizedBox(width:28),Expanded(child:Center(child:Text('一',style:TextStyle(color:_sub,fontSize:11)))),Expanded(child:Center(child:Text('二',style:TextStyle(color:_sub,fontSize:11)))),Expanded(child:Center(child:Text('三',style:TextStyle(color:_sub,fontSize:11)))),Expanded(child:Center(child:Text('四',style:TextStyle(color:_sub,fontSize:11)))),Expanded(child:Center(child:Text('五',style:TextStyle(color:_sub,fontSize:11)))),]),constSizedBox(height:8),...List.generate(5,(row){finalcolors=[_primary,_accent,_amber,_green,_purple];returnPadding(padding:constEdgeInsets.only(bottom:6),child:Row(children:[SizedBox(width:28,child:Text('${row+1}',textAlign:TextAlign.center,style:constTextStyle(color:_sub,fontSize:11)),),...List.generate(5,(col){finalhas=(row+col)%3!=0;finalc=colors[(row+col)%colors.length];returnExpanded(child:Container(margin:EdgeInsets.only(right:col==4?0:4),height:32,decoration:BoxDecoration(color:has?c.withValues(alpha:0.18):Colors.transparent,borderRadius:BorderRadius.circular(6),),alignment:Alignment.center,child:Text(has?'课':'',style:TextStyle(color:c,fontSize:10,fontWeight:FontWeight.w700)),));}),]),);}),]),);}课表数据存在分布式数据对象里,多端实时同步。桌面服务卡片可以显示"下节课 10 分钟后 · 操作系统 · A201"。
从「本周课表网格」的时间表传统形式与移动端适配设计角度再补一段。本周课表是大学生使用频率最高的视图——必须把传统的「7 天 × 12 节」二维网格用 Flutter 优雅地实现。这段网格用 Row 嵌入 Column 的双层结构,纵向是节次(1-12 节)、横向是星期(周一到周日),每个格子代表「某天某节」是否有课。有课的格子用对应学科主题色填充,配合课程名简写让用户一眼识别。鸿蒙 6.0 端的 Skia 渲染对这种密集网格的开销极低,即使全部 84 个格子(7×12)同屏也不会卡顿。如果未来要扩展支持「按周切换 + 颜色自定义」(让学生自己给每门课指定颜色),可以做一个偏好设置页,骨架不变。
心得
工具类 App 的视觉灵魂是"信息密度高但有秩序"——靛蓝色给专业,橙色用于强调,白色卡片承载内容。开发时最容易犯的错是把课表网格做得过于密集,让用户看不清。我的策略是用浅色背景 + 主色文字的"轻 chip"做每节课,既清晰又不刺眼。从能力扩展角度,课程表应用最值得在鸿蒙端打造的是"分布式课表 + PushKit 课前提醒 + 桌面服务卡片"三件套——多端同步让课表无处不在、推送让用户不忘上课、桌面卡片让"下节课"一眼可见。
总结
本篇实现了 Harmony 6.0 端的课程表首页,5 个模块、纯 UI、零依赖、约 380 行代码。第十三组的"编程学习 / AR 汉字 / 课程表"三个迥异的教育类场景共用同一份骨架。从扩展角度建议生产业务里:把课表接入分布式数据对象;把课前提醒接入 PushKit;把"下节课"做成 FormExtensionAbility 桌面卡片;把学籍接入 HMS Account;把 GPA 计算接入 AI 助手能力做学业建议。下一篇进入第十四组——考研倒计时 / 驾考模拟 / 儿童数学。