Flutter for OpenHarmony 身体健康状况记录App实战 - 睡眠分析实现
本文介绍了睡眠分析页面的实现方案,主要包含睡眠数据汇总卡片和本周睡眠统计图表。汇总卡片使用紫色渐变背景展示平均睡眠时长、入睡/起床时间和质量评估。柱状图直观显示每日睡眠时长,通过不同颜色区分睡眠质量。页面采用响应式设计,适配不同屏幕尺寸,帮助用户清晰了解睡眠规律和质量,为作息调整提供数据支持。
#
前言
睡眠分析页面帮助用户了解自己的睡眠规律和质量。通过统计本周的睡眠数据,用户可以发现自己的睡眠问题,调整作息习惯。
这篇文章会讲解睡眠分析页面的实现,包括平均睡眠时长展示、入睡起床时间统计、本周睡眠柱状图等功能。
页面整体结构
睡眠分析页面包含汇总数据卡片和本周睡眠统计两个主要部分。
class SleepAnalysisPage extends StatelessWidget {
const SleepAnalysisPage({super.key});
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFFAFAFC),
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios_rounded, size: 20.w),
onPressed: () => Get.back()
),
title: Text('睡眠分析', style: TextStyle(fontSize: 17.sp, fontWeight: FontWeight.w600)),
centerTitle: true,
),
body: SingleChildScrollView(
padding: EdgeInsets.all(20.w),
child: Column(
children: [
_buildSummaryCard(),
SizedBox(height: 20.h),
_buildWeekStats(),
],
),
),
);
}
}
页面使用统一的浅灰色背景和透明 AppBar,和其他统计页面保持一致的视觉风格。
睡眠汇总卡片
汇总卡片使用紫色渐变背景,展示本周平均睡眠时长和相关统计数据。
Widget _buildSummaryCard() {
return Container(
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF845EC2), Color(0xFFA178DF)]
),
borderRadius: BorderRadius.circular(24.r),
),
child: Column(
children: [
Text('本周平均睡眠', style: TextStyle(fontSize: 13.sp, color: Colors.white70)),
SizedBox(height: 8.h),
Text('7小时15分', style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.w700,
color: Colors.white
)),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildMiniStat('入睡', '23:12'),
_buildMiniStat('起床', '06:27'),
_buildMiniStat('质量', '良好'),
],
),
],
),
);
}
Widget _buildMiniStat(String label, String value) {
return Column(
children: [
Text(value, style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.white
)),
SizedBox(height: 2.h),
Text(label, style: TextStyle(fontSize: 11.sp, color: Colors.white60)),
],
);
}
渐变色从 #845EC2 到 #A178DF,是一个优雅的紫色系,和睡眠主题非常契合。平均睡眠时长使用 32sp 的大字号居中显示。
底部三个迷你统计项展示平均入睡时间、平均起床时间和睡眠质量评估。用 spaceAround 让三个项目均匀分布。
睡眠质量评估
根据平均睡眠时长评估睡眠质量:
String _getSleepQuality(double avgHours) {
if (avgHours < 6) {
return '不足';
} else if (avgHours < 7) {
return '一般';
} else if (avgHours <= 8) {
return '良好';
} else if (avgHours <= 9) {
return '很好';
} else {
return '过多';
}
}
成年人建议每天睡 7-9 小时,低于 6 小时为睡眠不足,超过 9 小时可能也不太健康。这个方法根据平均时长返回对应的质量评价。
本周睡眠柱状图
柱状图直观地展示本周每天的睡眠时长,让用户一眼看出哪天睡得好、哪天睡得少。
Widget _buildWeekStats() {
final days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
final hours = [7.5, 6.8, 8.0, 7.2, 6.5, 8.5, 7.3];
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.r)
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('本周睡眠', style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF1A1A2E)
)),
SizedBox(height: 20.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(7, (i) => Column(
children: [
Container(
width: 32.w,
height: (hours[i] * 16).h,
decoration: BoxDecoration(
color: hours[i] >= 7
? const Color(0xFF845EC2)
: const Color(0xFF845EC2).withOpacity(0.3),
borderRadius: BorderRadius.circular(6.r),
),
),
SizedBox(height: 8.h),
Text(days[i], style: TextStyle(fontSize: 10.sp, color: Colors.grey[500])),
],
)),
),
],
),
);
}
柱状图的高度根据睡眠时长动态计算,hours[i] * 16 把小时数转换成像素高度。睡眠达到 7 小时以上的用实心紫色,不足 7 小时的用淡紫色,让用户能快速识别睡眠不足的日子。
每个柱子下方显示星期几的标签,用灰色小字不会太抢眼。
柱状图高度计算
为了让柱状图显示效果更好,可以动态计算高度比例:
double _calculateBarHeight(double hours, double maxHours) {
final maxHeight = 120.h; // 最大高度
final minHeight = 20.h; // 最小高度
if (maxHours == 0) return minHeight;
final ratio = hours / maxHours;
return minHeight + (maxHeight - minHeight) * ratio;
}
这个方法根据当前值和最大值计算柱子高度,确保最高的柱子不会太高,最矮的柱子也不会太矮。
睡眠规律分析
除了时长,睡眠规律也很重要。可以分析用户的入睡和起床时间是否规律:
Widget _buildRegularityAnalysis() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('作息规律', style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: const Color(0xFF1A1A2E),
)),
SizedBox(height: 12.h),
_buildRegularityItem('入睡时间', '22:45 - 23:30', '波动45分钟'),
SizedBox(height: 10.h),
_buildRegularityItem('起床时间', '06:15 - 07:00', '波动45分钟'),
SizedBox(height: 12.h),
Container(
padding: EdgeInsets.all(10.w),
decoration: BoxDecoration(
color: const Color(0xFF845EC2).withOpacity(0.08),
borderRadius: BorderRadius.circular(8.r),
),
child: Row(
children: [
Icon(Icons.check_circle_outline_rounded, size: 16.w, color: const Color(0xFF845EC2)),
SizedBox(width: 8.w),
Expanded(
child: Text(
'您的作息比较规律,继续保持',
style: TextStyle(fontSize: 12.sp, color: const Color(0xFF845EC2)),
),
),
],
),
),
],
),
);
}
Widget _buildRegularityItem(String label, String range, String variance) {
return Row(
children: [
SizedBox(
width: 70.w,
child: Text(label, style: TextStyle(fontSize: 13.sp, color: Colors.grey[600])),
),
Expanded(
child: Text(range, style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: const Color(0xFF1A1A2E),
)),
),
Text(variance, style: TextStyle(fontSize: 11.sp, color: Colors.grey[400])),
],
);
}
规律分析展示入睡和起床时间的范围以及波动幅度。波动越小说明作息越规律,对健康越有益。
睡眠建议
根据睡眠数据生成个性化的建议:
List<String> _generateSleepTips(double avgHours, double variance) {
List<String> tips = [];
if (avgHours < 7) {
tips.add('您的平均睡眠时间不足7小时,建议早点入睡');
} else if (avgHours > 9) {
tips.add('睡眠时间过长可能影响精力,建议控制在7-9小时');
} else {
tips.add('您的睡眠时长在健康范围内,继续保持');
}
if (variance > 60) {
tips.add('作息时间波动较大,建议固定入睡和起床时间');
} else {
tips.add('您的作息比较规律,这对健康很有益');
}
tips.add('睡前避免使用电子设备,有助于提高睡眠质量');
return tips;
}
建议内容根据平均睡眠时长和作息规律动态生成,给用户提供有针对性的指导。
睡眠趋势对比
可以添加和上周的对比,让用户了解自己的睡眠变化:
Widget _buildWeekComparison() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('与上周对比', style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: const Color(0xFF1A1A2E),
)),
SizedBox(height: 4.h),
Text('平均睡眠时长', style: TextStyle(
fontSize: 11.sp,
color: Colors.grey[400],
)),
],
),
),
Row(
children: [
Icon(Icons.arrow_upward_rounded, size: 16.w, color: const Color(0xFF00C9A7)),
SizedBox(width: 4.w),
Text('+18分钟', style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF00C9A7),
)),
],
),
],
),
);
}
对比数据用箭头和颜色表示变化方向,增加显示绿色向上箭头,减少显示红色向下箭头。
睡眠目标达成
展示本周睡眠目标的达成情况:
Widget _buildGoalAchievement() {
final targetDays = 7;
final achievedDays = 5; // 达到7小时以上的天数
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('睡眠目标', style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: const Color(0xFF1A1A2E),
)),
Text('$achievedDays/$targetDays 天', style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF845EC2),
)),
],
),
SizedBox(height: 12.h),
Row(
children: List.generate(7, (i) => Expanded(
child: Container(
margin: EdgeInsets.only(right: i < 6 ? 4.w : 0),
height: 6.h,
decoration: BoxDecoration(
color: i < achievedDays
? const Color(0xFF845EC2)
: Colors.grey[200],
borderRadius: BorderRadius.circular(3.r),
),
),
)),
),
SizedBox(height: 8.h),
Text(
'每天睡眠7小时以上',
style: TextStyle(fontSize: 11.sp, color: Colors.grey[400]),
),
],
),
);
}
用七个小方块表示一周七天,达成目标的用紫色填充,未达成的用灰色。这种可视化方式让用户一眼就能看出自己的达成情况。
小结
睡眠分析页面通过紫色渐变卡片展示平均数据,用柱状图直观呈现每日睡眠时长,再配合规律分析和目标达成展示,帮助用户全面了解自己的睡眠状况。
核心设计要点包括:柱状图用颜色深浅区分达标与否,规律分析展示时间波动范围,目标达成用进度条可视化。这些设计让用户能发现自己的睡眠问题,有针对性地改善作息习惯。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)