开源鸿蒙跨平台Flutter开发:喝水时间提醒应用
开源鸿蒙跨平台饮水健康应用摘要 该项目是一款基于Flutter开发的智能饮水提醒应用,支持鸿蒙OS/Web等多平台。核心功能包括: 个性化计算:根据体重、活动量(5个等级)智能推荐饮水量 智能提醒:提供标准/健康/运动/自定义4种提醒模式 数据可视化:记录每次饮水(小/中/大杯等5种类型),生成趋势图表 目标管理:设置4级健康目标(初饮者到水分充足) 技术栈采用Flutter 3.0+Dart 2
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
喝水时间提醒是一款智能健康应用,根据用户的体重和活动量,智能计算并提醒喝水时间,帮助用户养成健康的饮水习惯。应用支持记录每天的喝水量,生成饮水趋势图表,提供个性化的饮水建议,让用户轻松掌握自己的饮水情况。
应用以清新的蓝色为主色调,象征水的纯净与健康。涵盖饮水概览、智能提醒、记录管理、数据统计四大模块。用户可以设置个人信息、查看饮水记录、接收智能提醒、分析饮水趋势,让健康饮水成为一种习惯。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 个人设置 | 体重、活动量、目标设置 | 表单输入 |
| 智能提醒 | 根据个人数据计算提醒时间 | 算法计算 |
| 饮水记录 | 记录每次饮水量 | 快捷记录 |
| 数据统计 | 每日/每周/每月饮水统计 | 数据可视化 |
| 趋势分析 | 饮水习惯趋势分析 | 图表展示 |
| 目标管理 | 设定每日饮水目标 | 目标追踪 |
| 提醒管理 | 自定义提醒时间和方式 | 提醒设置 |
| 数据导出 | 导出饮水记录数据 | 数据导出 |
1.3 活动量等级定义
| 序号 | 等级名称 | Emoji | 描述 | 饮水量系数 |
|---|---|---|---|---|
| 1 | sedentary | 🪑 | 久坐不动 | 1.0 |
| 2 | 轻度活动 | 🚶 | 轻度运动 | 1.2 |
| 3 | 中度活动 | 🏃 | 中等运动 | 1.5 |
| 4 | 重度活动 | 🏋️ | 高强度运动 | 1.8 |
| 5 | 极重活动 | 🚴 | 极高强度运动 | 2.0 |
1.4 饮水提醒模式定义
| 序号 | 模式名称 | Emoji | 描述 | 提醒频率 |
|---|---|---|---|---|
| 1 | 标准模式 | 📱 | 标准饮水提醒 | 每小时 |
| 2 | 健康模式 | 💪 | 健康饮水计划 | 每45分钟 |
| 3 | 运动模式 | 🏃 | 运动饮水计划 | 每30分钟 |
| 4 | 自定义 | ⚙️ | 自定义提醒 | 自定义 |
1.5 饮水类型定义
| 序号 | 类型名称 | Emoji | 容量 | 描述 |
|---|---|---|---|---|
| 1 | 小杯 | 🥛 | 100ml | 小容量饮水 |
| 2 | 中杯 | 🧊 | 200ml | 标准容量 |
| 3 | 大杯 | 🍶 | 300ml | 大容量饮水 |
| 4 | 水瓶 | 🧴 | 500ml | 水瓶容量 |
| 5 | 自定义 | ⚙️ | 自定义 | 自定义容量 |
1.6 健康目标定义
| 序号 | 目标名称 | Emoji | 描述 | 达成条件 |
|---|---|---|---|---|
| 1 | 初饮者 | 🥤 | 开始饮水习惯 | 连续7天达标 |
| 2 | 坚持者 | 💧 | 养成饮水习惯 | 连续30天达标 |
| 3 | 健康达人 | 🏆 | 保持健康习惯 | 连续90天达标 |
| 4 | 水分充足 | 💪 | 最佳饮水状态 | 连续180天达标 |
1.7 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | Provider | >= 6.0.0 |
| 数据存储 | SharedPreferences | >= 2.0.0 |
| 图表库 | FL Chart | >= 0.55.0 |
| 通知 | Flutter Local Notifications | >= 14.0.0 |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.8 项目结构
lib/
└── main_water_reminder.dart
├── WaterReminderApp # 应用入口
├── ActivityLevel # 活动量等级枚举
├── ReminderMode # 提醒模式枚举
├── DrinkType # 饮水类型枚举
├── HealthGoal # 健康目标枚举
├── UserProfile # 用户档案模型
├── DrinkRecord # 饮水记录模型
├── ReminderSetting # 提醒设置模型
├── WaterReminderHomePage # 主页面(底部导航)
├── _buildOverviewPage # 概览页面
├── _buildReminderPage # 提醒页面
├── _buildRecordPage # 记录页面
├── _buildStatisticsPage # 统计页面
├── WaterIntakeCalculator # 饮水量计算器
└── WaterTrendPainter # 饮水趋势绘制器
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 提醒流程
三、核心模块设计
3.1 数据模型设计
3.1.1 活动量等级枚举 (ActivityLevel)
enum ActivityLevel {
sedentary(label: '久坐不动', emoji: '🪑', description: '很少运动', multiplier: 1.0),
light(label: '轻度活动', emoji: '🚶', description: '轻度运动', multiplier: 1.2),
moderate(label: '中度活动', emoji: '🏃', description: '中等运动', multiplier: 1.5),
heavy(label: '重度活动', emoji: '🏋️', description: '高强度运动', multiplier: 1.8),
extreme(label: '极重活动', emoji: '🚴', description: '极高强度运动', multiplier: 2.0);
final String label;
final String emoji;
final String description;
final double multiplier;
const ActivityLevel({
required this.label,
required this.emoji,
required this.description,
required this.multiplier,
});
}
3.1.2 提醒模式枚举 (ReminderMode)
enum ReminderMode {
standard(label: '标准模式', emoji: '📱', description: '标准饮水提醒', interval: 60),
healthy(label: '健康模式', emoji: '💪', description: '健康饮水计划', interval: 45),
sport(label: '运动模式', emoji: '🏃', description: '运动饮水计划', interval: 30),
custom(label: '自定义', emoji: '⚙️', description: '自定义提醒', interval: 0);
final String label;
final String emoji;
final String description;
final int interval;
const ReminderMode({
required this.label,
required this.emoji,
required this.description,
required this.interval,
});
}
3.1.3 用户档案模型 (UserProfile)
class UserProfile {
final String id;
final String name;
final double weight;
final ActivityLevel activityLevel;
final int dailyGoal;
final DateTime createdAt;
const UserProfile({
required this.id,
required this.name,
required this.weight,
required this.activityLevel,
required this.dailyGoal,
required this.createdAt,
});
UserProfile copyWith({
String? id,
String? name,
double? weight,
ActivityLevel? activityLevel,
int? dailyGoal,
DateTime? createdAt,
}) {
return UserProfile(
id: id ?? this.id,
name: name ?? this.name,
weight: weight ?? this.weight,
activityLevel: activityLevel ?? this.activityLevel,
dailyGoal: dailyGoal ?? this.dailyGoal,
createdAt: createdAt ?? this.createdAt,
);
}
}
3.1.4 饮水记录模型 (DrinkRecord)
class DrinkRecord {
final String id;
final DateTime timestamp;
final int amount;
final String type;
final String notes;
const DrinkRecord({
required this.id,
required this.timestamp,
required this.amount,
required this.type,
required this.notes,
});
}
3.1.5 饮水量分布
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 概览页结构
3.2.3 提醒页结构
3.2.4 统计页结构
3.3 饮水量计算逻辑
3.4 数据分析逻辑
四、UI设计规范
4.1 配色方案
应用以清新的蓝色为主色调,象征水的纯净与健康:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #2196F3 (Blue) | 导航、主题元素 |
| 辅助色 | #42A5F5 | 概览页面 |
| 第三色 | #64B5F6 | 提醒页面 |
| 强调色 | #90CAF9 | 记录页面 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 信息卡片 |
| 警告色 | #FF9800 | 提醒通知 |
| 成功色 | #4CAF50 | 目标达成 |
4.2 活动量等级配色
| 等级 | 色值 | 视觉效果 |
|---|---|---|
| 久坐不动 | #9E9E9E | 灰色 |
| 轻度活动 | #4CAF50 | 绿色 |
| 中度活动 | #2196F3 | 蓝色 |
| 重度活动 | #FF9800 | 橙色 |
| 极重活动 | #F44336 | 红色 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 饮水量显示 | 48px | Bold | 主色 |
| 目标进度 | 20px | Bold | #000000 |
| 提醒时间 | 16px | Regular | #333333 |
| 统计数据 | 14px | Regular | #666666 |
| 提示文字 | 12px | Regular | #999999 |
4.4 组件规范
4.4.1 饮水概览卡片
┌─────────────────────────────────────┐
│ 饮水概览 │
│ │
│ ┌─────────────────────────────┐ │
│ │ 💧 今日饮水 │ │
│ │ 1200ml / 2000ml │ │
│ │ ━━━━━━━━━●────────── 60% │ │
│ │ 剩余: 800ml │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
4.4.2 快速记录卡片
┌─────────────────────────────────────┐
│ 快速记录 │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 🥛 │ │ 🧊 │ │ 🍶 │ │
│ │ 100ml │ │ 200ml │ │ 300ml │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ 自定义: [ ] ml │ │
│ └─────────────────────────────┘ │
│ [记录] │
└─────────────────────────────────────┘
4.4.3 提醒设置卡片
┌─────────────────────────────────────┐
│ 提醒设置 │
│ │
│ 提醒模式: [标准模式 ▼] │
│ │
│ 提醒时间: │
│ 08:00 · 09:00 · 10:00 · 11:00 │
│ 12:00 · 13:00 · 14:00 · 15:00 │
│ 16:00 · 17:00 · 18:00 · 19:00 │
│ │
│ [开启提醒] [关闭提醒] │
└─────────────────────────────────────┘
4.4.4 统计图表卡片
┌─────────────────────────────────────┐
│ 饮水趋势 │
│ │
│ 近7天饮水情况 │
│ ━━━━━━━━━━━━━━━━━━━━━━ │
│ 📈 平均: 1800ml/天 │
│ 📊 最高: 2200ml (周三) │
│ 📉 最低: 1500ml (周六) │
│ │
│ [查看详情] │
└─────────────────────────────────────┘
4.4.5 健康建议卡片
┌─────────────────────────────────────┐
│ 健康建议 │
│ │
│ 💡 饮水小贴士 │
│ │
│ • 早晨起床后喝一杯温水 │
│ • 每小时至少喝200ml水 │
│ • 运动前后适当增加饮水量 │
│ • 避免一次性大量饮水 │
└─────────────────────────────────────┘
五、核心功能实现
5.1 饮水量计算器实现
class WaterIntakeCalculator {
int calculateDailyIntake(UserProfile profile) {
final baseIntake = profile.weight * 30; // 基础饮水量 = 体重(kg) * 30ml
final adjustedIntake = baseIntake * profile.activityLevel.multiplier;
return adjustedIntake.round();
}
List<TimeOfDay> calculateReminderTimes(UserProfile profile, ReminderMode mode) {
List<TimeOfDay> times = [];
int interval = mode.interval;
if (interval == 0) {
// 自定义模式,使用默认间隔
interval = 60;
}
int startHour = 8;
int endHour = 20;
for (int hour = startHour; hour <= endHour; hour += interval ~/ 60) {
times.add(TimeOfDay(hour: hour, minute: 0));
if (interval < 60) {
times.add(TimeOfDay(hour: hour, minute: interval));
}
}
return times;
}
}
5.2 提醒管理器实现
class ReminderManager {
void scheduleReminders(ReminderSetting setting) {
if (!setting.enabled) return;
for (var time in setting.reminderTimes) {
_scheduleReminder(time, setting.sound);
}
}
void _scheduleReminder(TimeOfDay time, String sound) {
// 计算今天的提醒时间
final now = DateTime.now();
final reminderTime = DateTime(
now.year,
now.month,
now.day,
time.hour,
time.minute,
);
// 如果时间已过,设置为明天
final scheduledTime = reminderTime.isBefore(now)
? reminderTime.add(const Duration(days: 1))
: reminderTime;
// 计算延迟时间
final delay = scheduledTime.difference(now);
// 调度提醒
Future.delayed(delay, () {
showNotification('该喝水了!保持水分充足');
});
}
void showNotification(String message) {
// 显示通知
print('🔔 $message');
}
void cancelReminders() {
// 取消所有提醒
}
}
5.3 数据分析器实现
class DataAnalyzer {
Map<String, int> analyzeDailyIntake(List<DrinkRecord> records) {
Map<String, int> dailyIntake = {};
for (var record in records) {
final date = '${record.timestamp.year}-${record.timestamp.month}-${record.timestamp.day}';
dailyIntake[date] = (dailyIntake[date] ?? 0) + record.amount;
}
return dailyIntake;
}
Map<String, int> analyzeWeeklyIntake(List<DrinkRecord> records) {
Map<String, int> weeklyIntake = {};
for (var record in records) {
final weekStart = record.timestamp.subtract(Duration(days: record.timestamp.weekday - 1));
final weekKey = '${weekStart.year}-${weekStart.month}-${weekStart.day}';
weeklyIntake[weekKey] = (weeklyIntake[weekKey] ?? 0) + record.amount;
}
return weeklyIntake;
}
Map<String, int> analyzeMonthlyIntake(List<DrinkRecord> records) {
Map<String, int> monthlyIntake = {};
for (var record in records) {
final monthKey = '${record.timestamp.year}-${record.timestamp.month}';
monthlyIntake[monthKey] = (monthlyIntake[monthKey] ?? 0) + record.amount;
}
return monthlyIntake;
}
Map<String, int> analyzeHourlyIntake(List<DrinkRecord> records) {
Map<String, int> hourlyIntake = {};
for (var record in records) {
final hourKey = '${record.timestamp.hour}:00';
hourlyIntake[hourKey] = (hourlyIntake[hourKey] ?? 0) + record.amount;
}
return hourlyIntake;
}
}
5.4 饮水记录实现
void _recordDrink(int amount, String type) {
setState(() {
_isRecording = true;
});
final record = DrinkRecord(
id: 'record_${DateTime.now().millisecondsSinceEpoch}',
timestamp: DateTime.now(),
amount: amount,
type: type,
notes: '',
);
_drinkRecords.insert(0, record);
_updateDailyIntake();
setState(() {
_isRecording = false;
});
}
void _updateDailyIntake() {
final today = DateTime.now();
final todayRecords = _drinkRecords.where((record) {
return record.timestamp.year == today.year &&
record.timestamp.month == today.month &&
record.timestamp.day == today.day;
}).toList();
_todayIntake = todayRecords.fold(0, (sum, record) => sum + record.amount);
_progress = (_todayIntake / _userProfile.dailyGoal).clamp(0.0, 1.0);
}
5.5 目标达成检测实现
void _checkGoalAchievement() {
if (_todayIntake >= _userProfile.dailyGoal) {
if (!_goalAchievedToday) {
_goalAchievedToday = true;
_streakDays++;
_showGoalAchievement();
}
}
}
void _showGoalAchievement() {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('🎉 恭喜!'),
Text('今日饮水目标达成!连续 $streakDays 天'),
],
),
backgroundColor: Colors.green,
),
);
}
六、交互设计
6.1 饮水记录流程
6.2 提醒设置流程
6.3 数据分析流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 智能学习系统
学习功能:
- 分析用户饮水习惯
- 智能调整提醒时间
- 个性化饮水建议
- 季节饮水计划
7.2.2 社交分享功能
社交功能:
- 邀请好友一起喝水
- 饮水打卡分享
- 健康饮水挑战
- 排行榜竞争
7.2.3 云同步功能
同步功能:
- 多设备数据同步
- 数据备份恢复
- 云端存储
- 跨设备提醒
八、注意事项
8.1 开发注意事项
-
提醒可靠性:确保提醒能够及时准确发送
-
数据持久化:保证饮水记录数据不丢失
-
电池优化:提醒功能需考虑电池消耗
-
用户体验:记录操作需简单便捷
-
隐私保护:用户数据需安全存储
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 提醒不触发 | 系统限制 | 引导用户开启通知权限 |
| 数据丢失 | 未及时保存 | 增加自动保存机制 |
| 计算不准确 | 个人数据错误 | 提醒用户更新个人信息 |
| 电池消耗快 | 后台运行 | 优化提醒机制 |
| 界面卡顿 | 数据量过大 | 分页加载数据 |
8.3 使用技巧
💧 健康饮水小贴士 💧
最佳饮水时间
- 早晨起床后:一杯温水唤醒身体
- 餐前30分钟:促进消化
- 餐后1小时:帮助吸收
- 运动前:补充水分
- 运动后:及时补水
- 睡前1小时:适量饮水
饮水建议
- 每天至少8杯水(约2000ml)
- 小口慢饮,避免大口吞咽
- 选择温水,避免过冷过热
- 运动时增加饮水量
- 保持规律的饮水习惯
- 避免用饮料代替水
健康益处
- 促进新陈代谢
- 维持皮肤健康
- 提高免疫力
- 改善消化功能
- 增强注意力
- 预防脱水
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
| Web浏览器 | Chrome 90+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_water_reminder.dart --web-port 8147
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_water_reminder.dart
# 代码分析
flutter analyze lib/main_water_reminder.dart
十、总结
喝水时间提醒应用通过智能提醒、饮水记录、数据分析等功能,帮助用户养成健康的饮水习惯。应用根据用户的体重和活动量,智能计算每日饮水量和提醒时间,让用户在正确的时间补充水分。
核心功能涵盖个人设置、智能提醒、饮水记录、数据统计四大模块。个人设置支持体重和活动量调整;智能提醒根据个人数据计算最佳饮水时间;饮水记录支持快速记录和自定义输入;数据统计提供详细的饮水趋势分析。
应用采用 Material Design 3 设计规范,以清新的蓝色为主色调,象征水的纯净与健康。通过本应用,希望能够帮助用户建立良好的饮水习惯,提高健康水平,让每一天都充满活力。
喝水时间提醒——让健康饮水成为习惯
更多推荐
所有评论(0)