Flutter 框架跨平台鸿蒙开发 - 疫苗接种记录
运行效果图// 唯一标识符// 姓名// 出生日期idNumber;// 身份证号(可选)phone;// 联系电话(可选)// 家庭关系avatar;// 头像(可选)基础信息包括ID、姓名、出生日期;扩展信息包括身份证号、电话、关系、头像。这种设计既满足了展示需求,又支持灵活的信息管理。// 唯一标识符// 成员ID// 疫苗类型// 疫苗名称// 接种日期hospital;// 接种机构(可
Flutter疫苗接种记录
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
项目概述
运行效果图



一、项目背景与目标
疫苗接种是预防传染病最有效的手段之一,对于个人和家庭的健康管理具有重要意义。然而,随着疫苗种类的增多和接种程序的复杂化,如何有效管理家庭成员的疫苗接种记录成为许多家庭面临的难题。传统的纸质记录容易丢失、难以查询,且无法及时提醒接种时间。本项目基于Flutter框架开发一款疫苗接种记录应用,旨在帮助家庭科学管理疫苗接种信息,确保每位家庭成员都能按时完成免疫规划。
项目的核心目标涵盖多个维度:构建完整的家庭成员管理系统,实现详细的疫苗接种记录管理,设计智能的接种提醒功能,打造便捷的查询和统计功能,以及确保应用的数据安全和隐私保护。通过本项目的开发,不仅能够深入理解Flutter在医疗健康类应用中的应用,更能掌握数据管理、状态维护、时间处理等核心技术要点。
应用场景分析
| 应用场景 | 功能需求 | 实现方式 |
|---|---|---|
| 儿童免疫 | 管理儿童免疫规划疫苗接种 | 家庭成员管理和接种提醒 |
| 成人接种 | 记录成人疫苗(流感、HPV等) | 多类型疫苗支持 |
| 出国旅行 | 记录旅行所需疫苗接种 | 疫苗证书生成 |
| 健康档案 | 建立家庭疫苗接种档案 | 历史记录查询和统计 |
核心价值主张
- 家庭管理:支持多位家庭成员,统一管理全家接种记录
- 智能提醒:自动计算下一针时间,提前提醒接种
- 完整记录:详细记录接种信息,包括批号、机构等
- 便捷查询:快速查询历史记录,支持多维度筛选
二、技术选型与架构设计
技术栈分析
本项目选用Flutter作为开发框架,主要基于以下考量:
- 跨平台能力:Flutter的跨平台特性能够同时支持Android和iOS平台,降低开发成本
- 声明式UI:声明式UI编程范式能够高效构建复杂的医疗记录界面
- 丰富组件库:丰富的Widget组件库为应用UI开发提供了坚实基础
- 优秀性能:优秀的性能表现确保了列表滚动和数据展示的流畅性
Dart语言作为Flutter的开发语言,具备强类型、异步编程支持、优秀的性能表现等特性。项目采用单文件架构,将所有应用逻辑集中在main_vaccination.dart文件中,这种设计既便于代码管理,又利于理解应用整体架构。
架构层次划分
应用架构采用分层设计思想,主要分为以下几个层次:
数据模型层:定义应用中的核心数据结构,包括FamilyMember(家庭成员实体)、VaccinationRecord(接种记录实体)、VaccineType(疫苗类型)、VaccinationStatus(接种状态)等类和枚举。这些模型类封装了疫苗接种的属性和行为,构成了应用逻辑的基础。
业务逻辑层:实现应用的核心功能逻辑,包括成员管理、记录管理、提醒计算、统计分析等。这一层是应用的心脏,决定了应用的功能性和可用性。
渲染表现层:负责应用界面的绘制和UI展示,使用Flutter的Material Design组件库实现现代化的界面设计,通过卡片、列表、弹窗等组件实现丰富的视觉效果。
状态管理层:管理应用的各种状态,包括家庭成员列表、接种记录列表、筛选条件、选中成员等,确保应用状态的一致性和可预测性。
核心功能模块详解
一、家庭成员管理
成员属性定义
家庭成员实体封装了完整的个人信息:
class FamilyMember {
final String id; // 唯一标识符
final String name; // 姓名
final DateTime birthDate; // 出生日期
final String? idNumber; // 身份证号(可选)
final String? phone; // 联系电话(可选)
final String relationship; // 家庭关系
final String? avatar; // 头像(可选)
}
基础信息包括ID、姓名、出生日期;扩展信息包括身份证号、电话、关系、头像。这种设计既满足了展示需求,又支持灵活的信息管理。
年龄计算
年龄通过计算属性动态获取:
int get age {
final now = DateTime.now();
int years = now.year - birthDate.year;
if (now.month < birthDate.month ||
(now.month == birthDate.month && now.day < birthDate.day)) {
years--;
}
return years;
}
年龄计算考虑了月份和日期,确保年龄的准确性。
成员选择器
首页使用横向滚动列表展示家庭成员:
Container(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _members.length + 1,
itemBuilder: (context, index) {
if (index == _members.length) {
return _buildAddMemberCard();
}
final member = _members[index];
final isSelected = _selectedMemberId == member.id;
return _buildMemberCard(member, isSelected);
},
),
)
成员选择器支持点击选中,选中后筛选该成员的接种记录。末尾显示"添加成员"按钮,方便快速添加新成员。
二、疫苗接种记录管理
记录属性定义
接种记录实体封装了完整的疫苗信息:
class VaccinationRecord {
final String id; // 唯一标识符
final String memberId; // 成员ID
final VaccineType vaccineType; // 疫苗类型
final String vaccineName; // 疫苗名称
final DateTime vaccinationDate; // 接种日期
final String? hospital; // 接种机构(可选)
final String? batchNumber; // 批号(可选)
final int doseNumber; // 剂次
final int totalDoses; // 总剂次
final VaccinationStatus status; // 接种状态
final DateTime? nextDoseDate; // 下一针时间(可选)
final String? notes; // 备注(可选)
final String? doctor; // 接种医生(可选)
}
基础信息包括ID、成员ID、疫苗信息、日期;扩展信息包括机构、批号、医生、备注等。这种设计既满足了展示需求,又支持完整的接种档案管理。
疫苗类型定义
应用支持十种常见疫苗类型:
enum VaccineType {
covid19, // 新冠疫苗 - 红色
hepatitisB, // 乙肝疫苗 - 橙色
bcg, // 卡介苗 - 绿色
polio, // 脊髓灰质炎疫苗 - 蓝色
dtp, // 百白破疫苗 - 紫色
measles, // 麻疹疫苗 - 粉色
influenza, // 流感疫苗 - 青色
hpv, // HPV疫苗 - 靛蓝色
rabies, // 狂犬疫苗 - 棕色
other, // 其他疫苗 - 灰色
}
每种类型对应不同的图标和颜色,便于用户快速识别疫苗类型。
| 疫苗类型 | 图标 | 颜色 | 适用人群 |
|---|---|---|---|
| 新冠疫苗 | coronavirus | 红色 | 全人群 |
| 乙肝疫苗 | health_and_safety | 橙色 | 新生儿、成人 |
| 卡介苗 | medical_services | 绿色 | 新生儿 |
| 脊灰疫苗 | vaccines | 蓝色 | 儿童 |
| 百白破 | medication | 紫色 | 儿童 |
| 麻疹疫苗 | healing | 粉色 | 儿童 |
| 流感疫苗 | sick | 青色 | 全人群 |
| HPV疫苗 | favorite | 靛蓝 | 女性 |
| 狂犬疫苗 | pets | 棕色 | 暴露人群 |
| 其他疫苗 | add_circle | 灰色 | 特殊需求 |
接种状态定义
应用支持四种接种状态:
enum VaccinationStatus {
pending, // 待接种 - 橙色
completed, // 已完成 - 绿色
overdue, // 已逾期 - 红色
scheduled, // 已预约 - 蓝色
}
状态帮助用户快速了解接种进度,逾期状态提供警示。
三、智能提醒系统
待办事项展示
首页展示待接种和逾期的疫苗记录:
Widget _buildUpcomingVaccinations() {
if (_upcomingRecords.isEmpty && _overdueRecords.isEmpty) {
return const SizedBox.shrink();
}
return Column(
children: [
if (_overdueRecords.isNotEmpty) ...[
..._overdueRecords.map((record) => _buildAlertCard(record, true)),
],
if (_upcomingRecords.isNotEmpty) ...[
..._upcomingRecords.take(3).map((record) => _buildAlertCard(record, false)),
],
],
);
}
逾期记录使用红色警示卡片,待接种记录使用橙色提示卡片,确保用户不会错过重要接种。
提醒卡片设计
提醒卡片使用醒目的颜色和图标:
Container(
decoration: BoxDecoration(
color: isOverdue ? Colors.red.withOpacity(0.1) : Colors.orange.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isOverdue ? Colors.red.withOpacity(0.3) : Colors.orange.withOpacity(0.3),
),
),
child: Row(
children: [
Icon(isOverdue ? Icons.warning : Icons.schedule),
Text('${member?.name} - ${record.vaccineName}'),
Text(isOverdue ? '已逾期,请尽快接种' : '第${record.doseNumber}针待接种'),
],
),
)
卡片颜色根据状态动态调整,逾期为红色,待接种为橙色,提供直观的视觉反馈。
四、记录筛选功能
成员筛选
用户可以按成员筛选接种记录:
List<VaccinationRecord> get _filteredRecords {
if (_selectedMemberId == null) return _records;
return _records.where((r) => r.memberId == _selectedMemberId).toList();
}
点击成员卡片切换筛选条件,再次点击取消筛选,显示全部记录。
状态筛选
应用自动分类不同状态的记录:
List<VaccinationRecord> get _upcomingRecords {
return _records.where((r) =>
r.status == VaccinationStatus.pending ||
r.status == VaccinationStatus.scheduled).toList();
}
List<VaccinationRecord> get _overdueRecords {
return _records.where((r) => r.status == VaccinationStatus.overdue).toList();
}
待办事项页面展示待接种和逾期记录,方便用户快速处理。
五、详情展示系统
记录详情弹窗
接种记录详情使用底部弹窗展示:
void _showRecordDetail(VaccinationRecord record) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => Container(
padding: const EdgeInsets.all(24),
child: Column(
children: [
// 疫苗图标和名称
// 详细信息列表
// 操作按钮
],
),
),
);
}
详情弹窗展示完整的接种信息,包括接种人、日期、剂次、机构、批号、医生等。
成员详情弹窗
成员详情展示接种统计:
void _showMemberDetail(FamilyMember member) {
final memberRecords = _records.where((r) => r.memberId == member.id).toList();
showModalBottomSheet(
builder: (context) => Column(
children: [
// 成员头像和基本信息
// 接种统计(总记录、已完成、待接种)
],
),
);
}
成员详情展示接种记录数量、已完成数量、待接种数量,帮助用户了解成员的接种进度。
UI界面开发
一、主界面布局
主界面采用底部导航栏设计,包含四个主要页面:
BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
selectedItemColor: Colors.blue,
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.list), label: '记录'),
BottomNavigationBarItem(icon: Icon(Icons.family_restroom), label: '成员'),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: '设置'),
],
)
四个页面分别是首页、记录、成员和设置,覆盖了应用的主要功能入口。
页面结构图
二、概览卡片设计
概览卡片使用渐变背景和统计数据:
Container(
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.blue.withOpacity(0.7)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.blue.withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 8),
),
],
),
child: Column(
children: [
Text('接种概览'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildOverviewItem(Icons.check_circle, '已完成', completed.toString()),
_buildOverviewItem(Icons.schedule, '待接种', pending.toString()),
_buildOverviewItem(Icons.event, '已预约', scheduled.toString()),
],
),
],
),
)
卡片展示已完成、待接种、已预约三个关键指标,让用户快速了解家庭接种情况。
视觉设计要点
- 渐变背景:蓝色渐变背景,营造专业医疗氛围
- 圆角设计:20px圆角,符合现代设计趋势
- 阴影效果:15px模糊半径,8px垂直偏移,营造悬浮感
- 统计图标:使用圆形背景的图标,视觉层次分明
- 成员数量:右上角显示家庭成员数量,快速了解家庭规模
三、成员选择器设计
成员选择器使用横向滚动的卡片:
Container(
width: 80,
decoration: BoxDecoration(
color: isSelected ? Colors.blue : Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isSelected ? Colors.blue : Colors.grey.shade300,
width: 2,
),
),
child: Column(
children: [
CircleAvatar(
radius: 20,
child: Icon(Icons.person),
),
Text(member.name),
Text('${member.age}岁'),
],
),
)
选中的成员卡片使用蓝色背景,未选中使用白色背景,提供清晰的视觉反馈。
四、记录卡片设计
记录卡片使用Material Design风格:
Card(
margin: const EdgeInsets.only(bottom: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: InkWell(
onTap: () => _showRecordDetail(record),
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: record.vaccineColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(record.vaccineIcon, color: record.vaccineColor),
),
Expanded(
child: Column(
children: [
Text(record.vaccineName),
Row(
children: [
Icon(Icons.person, size: 14),
Text(member?.name ?? ''),
Icon(Icons.calendar_today, size: 14),
Text('${record.vaccinationDate.year}/${record.vaccinationDate.month}/${record.vaccinationDate.day}'),
],
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: record.statusColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Text(record.statusText),
),
],
),
),
),
)
卡片左侧显示疫苗图标,中间显示名称和详情,右侧显示状态标签。
性能优化方案
一、列表渲染优化
记录列表使用ListView.builder实现按需渲染:
ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: _filteredRecords.length,
itemBuilder: (context, index) {
return _buildRecordCard(_filteredRecords[index]);
},
)
只有可见区域的卡片才会被创建和渲染,大幅降低了内存占用。
二、筛选计算优化
筛选使用getter属性实现:
List<VaccinationRecord> get _filteredRecords {
if (_selectedMemberId == null) return _records;
return _records.where((r) => r.memberId == _selectedMemberId).toList();
}
每次访问时重新计算,确保数据的实时性。对于频繁访问的计算结果,可以考虑使用缓存机制。
三、状态更新优化
状态更新使用setState触发局部刷新:
void _toggleMemberSelection(String? memberId) {
setState(() {
_selectedMemberId = memberId;
});
}
setState触发页面重建,但对于简单的列表应用,性能影响可接受。对于复杂场景,可以考虑使用Provider或Riverpod进行状态管理。
测试方案与步骤
一、功能测试
成员管理测试:验证添加成员功能;测试成员选择器;检查年龄计算准确性。
记录管理测试:验证添加记录功能;测试记录筛选功能;检查状态显示正确性。
提醒功能测试:验证待办事项展示;测试逾期提醒功能;检查提醒卡片显示。
详情展示测试:验证记录详情展示;测试成员详情展示;检查信息完整性。
二、边界测试
空列表测试:测试没有成员或记录时的界面展示。
年龄边界测试:测试刚出生和100岁以上成员的年龄计算。
日期边界测试:测试接种日期为今天、昨天、明天的处理。
多剂次测试:测试总剂次为1针、2针、3针等的显示。
三、用户体验测试
界面响应测试:测试页面切换的流畅性。
视觉体验测试:评估界面设计和颜色搭配。
操作便捷性测试:评估添加成员和记录的流程。
常见问题与解决方案
一、数据持久化问题
问题:应用重启后数据丢失
解决方案:使用shared_preferences或sqflite实现数据持久化
// 使用shared_preferences
final prefs = await SharedPreferences.getInstance();
final membersJson = _members.map((m) => jsonEncode(m.toJson())).toList();
await prefs.setStringList('members', membersJson);
二、提醒功能问题
问题:应用关闭后无法提醒
解决方案:集成系统通知功能
// 使用flutter_local_notifications
await flutterLocalNotificationsPlugin.show(
0,
'疫苗接种提醒',
'张三的新冠疫苗第2针即将到期',
notificationDetails,
);
三、隐私保护问题
问题:敏感信息泄露风险
解决方案:数据加密和权限控制
// 使用加密存储
final encryptedData = encrypt(jsonEncode(record.toJson()));
await secureStorage.write(key: 'records', value: encryptedData);
项目总结与展望
一、项目成果总结
本项目成功实现了一款功能完整、界面现代的疫苗接种记录应用,涵盖了医疗健康类应用开发的核心要素。通过Flutter框架的应用,实现了跨平台的应用体验,证明了Flutter在医疗健康类应用开发领域的可行性。
项目采用模块化设计思想,将应用功能划分为成员管理、记录管理、提醒系统、统计分析等独立模块,各模块职责明确,耦合度低,便于维护和扩展。
二、技术亮点总结
家庭管理:支持多位家庭成员统一管理,每个成员独立的接种档案。
多类型疫苗:支持十种常见疫苗类型,每种类型对应独特的图标和颜色。
智能提醒:自动识别待接种和逾期记录,提供醒目的提醒卡片。
详细记录:记录完整的接种信息,包括机构、批号、医生等。
便捷筛选:支持按成员筛选记录,快速定位目标信息。
三、未来优化方向
数据持久化:使用sqflite实现本地数据库存储,确保数据安全。
云端同步:实现数据云端备份和同步,支持多设备共享。
智能提醒:集成系统通知功能,在接种日期前自动提醒。
疫苗知识:添加疫苗知识库,帮助用户了解疫苗信息。
接种点查询:集成地图功能,查询附近接种点。
预约功能:支持在线预约接种服务。
证书生成:生成疫苗接种证书,方便出行和证明。
健康档案:扩展为完整的健康档案管理系统。
四、开发经验总结
通过本项目的开发,积累了宝贵的Flutter应用开发经验:
数据管理的重要性:医疗健康类应用的核心是数据管理,合理的数据结构设计能够简化业务逻辑,提高开发效率。
用户体验的核心地位:医疗健康类应用最终服务于用户的健康需求,从成员选择到记录查看,每个细节都需要精心打磨。
隐私保护的必要性:医疗数据属于敏感信息,需要考虑数据加密、权限控制等安全措施。
提醒功能的实用性:及时的提醒能够帮助用户按时接种,确保免疫效果。
本项目为Flutter医疗健康类应用开发提供了一个完整的实践案例,展示了如何实现成员管理、记录管理、智能提醒等核心功能,希望能够为相关开发者提供参考和启发,推动Flutter在医疗健康类应用开发领域的应用和发展。
更多推荐



所有评论(0)