Flutter 框架跨平台鸿蒙开发 - 过敏原查询应用开发文档
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图



1.1 应用简介
过敏原查询是一款专注于食物过敏信息查询与健康管理的移动应用,为用户提供全面的过敏原知识和食物安全信息。食物过敏已成为现代社会的常见健康问题,据统计全球约有2-4%的成年人和5-8%的儿童患有食物过敏。本应用帮助用户快速识别食物中的过敏原成分,了解过敏症状与预防措施,让饮食更加安全放心。
应用涵盖八大常见过敏原:牛奶、鸡蛋、花生、坚果、鱼类、甲壳类、大豆、小麦,每种过敏原都有详细的症状说明、常见食物、隐藏来源和替代食物推荐。食物查询功能让用户快速了解食物是否含有过敏原,为过敏人群的日常饮食提供科学指导。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 过敏原列表 | 展示八大过敏原详细信息 | ListView + Card |
| 食物查询 | 查询食物是否含过敏原 | GridView + Dialog |
| 分类筛选 | 按过敏原类型快速筛选 | FilterChip |
| 搜索功能 | 按关键词搜索过敏原/食物 | TextField过滤 |
| 过敏原详情 | 症状、食物、替代品完整展示 | 详情页面 |
| 风险等级 | 高/中/低风险分级标识 | 颜色标签 |
| 隐藏来源 | 加工食品中的隐蔽过敏原 | 列表展示 |
1.3 过敏原记录字段
| 字段 | 类型 | 说明 |
|---|---|---|
| 过敏原ID | String | 唯一标识 |
| 过敏原名称 | String | 过敏原名称 |
| 过敏原类型 | AllergenType | 八大过敏原分类 |
| 过敏说明 | String | 详细描述 |
| 过敏症状 | List | 常见症状列表 |
| 常见食物 | List | 含该过敏原的食物 |
| 隐藏来源 | List | 加工食品中的隐蔽来源 |
| 替代食物 | List | 可替代的食物推荐 |
| 预防建议 | String | 预防措施说明 |
| 风险等级 | AllergenLevel | 高/中/低风险 |
1.4 食物记录字段
| 字段 | 类型 | 说明 |
|---|---|---|
| 食物ID | String | 唯一标识 |
| 食物名称 | String | 食物名称 |
| 食物分类 | String | 食物类别 |
| 过敏原列表 | List | 含有的过敏原 |
| 安全标识 | bool | 是否无过敏原 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 目标平台 | 鸿蒙OS | API 21+ |
1.6 项目结构
lib/
└── main_allergen.dart
├── AllergenApp # 应用入口
├── AllergenType # 过敏原类型枚举
├── AllergenLevel # 风险等级枚举
├── Allergen # 过敏原数据模型
├── FoodItem # 食物数据模型
├── AllergenPage # 主页面
│ ├── _buildTypeChips() # 类型筛选条
│ ├── _buildSearchBar() # 搜索栏
│ ├── _buildAllergensList() # 过敏原列表
│ ├── _buildFoodsList() # 食物列表
│ ├── _buildAllergenCard() # 过敏原卡片
│ ├── _buildFoodCard() # 食物卡片
│ └── _showFoodDetail() # 食物详情弹窗
└── AllergenDetailPage # 过敏原详情页面
└── _buildListSection() # 列表区块构建
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 数据流程图
2.4 过敏原详情展示流程
三、核心模块设计
3.1 数据模型设计
3.1.1 过敏原类型枚举 (AllergenType)
enum AllergenType {
milk, // 牛奶
egg, // 鸡蛋
peanut, // 花生
treeNut, // 坚果
fish, // 鱼类
shellfish, // 甲壳类
soy, // 大豆
wheat, // 小麦
other, // 其他
}
3.1.2 过敏原类型属性映射
| 类型 | 中文名称 | 表情符号 | 主题颜色 |
|---|---|---|---|
| milk | 牛奶 | 🥛 | 蓝色 |
| egg | 鸡蛋 | 🥚 | 琥珀色 |
| peanut | 花生 | 🥜 | 棕色 |
| treeNut | 坚果 | 🌰 | 橙色 |
| fish | 鱼类 | 🐟 | 青色 |
| shellfish | 甲壳类 | 🦐 | 红色 |
| soy | 大豆 | 🫘 | 绿色 |
| wheat | 小麦 | 🌾 | 黄色 |
3.1.3 风险等级枚举 (AllergenLevel)
enum AllergenLevel {
high, // 高风险
medium, // 中风险
low, // 低风险
}
3.1.4 风险等级属性映射
| 等级 | 中文名称 | 主题颜色 |
|---|---|---|
| high | 高风险 | 红色 |
| medium | 中风险 | 橙色 |
| low | 低风险 | 绿色 |
3.1.5 过敏原模型 (Allergen)
class Allergen {
final String id; // 唯一标识
final String name; // 过敏原名称
final AllergenType type; // 过敏原类型
final String description; // 过敏说明
final List<String> symptoms; // 过敏症状
final List<String> foods; // 常见食物
final List<String> hiddenFoods; // 隐藏来源
final List<String> alternatives; // 替代食物
final String prevention; // 预防建议
final AllergenLevel level; // 风险等级
String get typeName; // 类型中文名
Color get typeColor; // 类型主题色
String get typeEmoji; // 类型表情
String get levelText; // 等级中文名
Color get levelColor; // 等级主题色
}
3.1.6 食物模型 (FoodItem)
class FoodItem {
final String id; // 唯一标识
final String name; // 食物名称
final String category; // 食物分类
final List<AllergenType> allergens; // 过敏原列表
final String emoji; // 表情符号
final bool isSafe; // 是否安全
}
3.2 筛选过滤算法
3.2.1 过敏原过滤流程
3.2.2 过滤实现
List<Allergen> get _filteredAllergens {
var allergens = _allergens.toList();
// 类型筛选
if (_selectedType != null) {
allergens = allergens.where((a) => a.type == _selectedType).toList();
}
// 关键词搜索
if (_searchQuery.isNotEmpty) {
allergens = allergens.where((a) {
return a.name.contains(_searchQuery) ||
a.typeName.contains(_searchQuery) ||
a.description.contains(_searchQuery) ||
a.foods.any((f) => f.contains(_searchQuery));
}).toList();
}
return allergens;
}
3.2.3 食物过滤实现
List<FoodItem> get _filteredFoods {
var foods = _foods.toList();
// 类型筛选(筛选含有该过敏原的食物)
if (_selectedType != null) {
foods = foods.where((f) => f.allergens.contains(_selectedType)).toList();
}
// 关键词搜索
if (_searchQuery.isNotEmpty) {
foods = foods.where((f) {
return f.name.contains(_searchQuery) ||
f.category.contains(_searchQuery);
}).toList();
}
return foods;
}
3.3 页面结构设计
3.3.1 主页面布局
3.3.2 详情页面布局
┌─────────────────────────────────────────────────────────────┐
│ AppBar: 牛奶过敏 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🥛 牛奶 │ │
│ │ 牛奶过敏 │ │
│ │ [高风险] │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ℹ️ 过敏说明 │ │
│ │ 牛奶过敏是常见的食物过敏之一... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🩹 过敏症状 │ │
│ │ [皮疹] [荨麻疹] [呕吐] [腹泻] [呼吸困难]... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🍽️ 常见食物 │ │
│ │ [牛奶] [奶粉] [奶油] [黄油] [奶酪]... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 👁️ 隐藏来源 │ │
│ │ [面包] [蛋糕] [饼干] [巧克力]... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🔄 替代食物 │ │
│ │ [豆奶] [杏仁奶] [燕麦奶] [椰奶]... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🛡️ 预防建议 │ │
│ │ 仔细阅读食品标签,避免含乳制品成分的食物... │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.4 状态管理
3.4.1 核心状态变量
class _AllergenPageState extends State<AllergenPage> {
final List<Allergen> _allergens = []; // 所有过敏原
final List<FoodItem> _foods = []; // 所有食物
String _searchQuery = ''; // 搜索关键词
AllergenType? _selectedType; // 选中的类型筛选
int _currentIndex = 0; // 当前Tab索引
}
四、UI设计规范
4.1 配色方案
应用采用红色主题风格,体现过敏警示的重要性:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | Red | AppBar、按钮、警示 |
| 高风险 | Red | 高风险过敏原标识 |
| 中风险 | Orange | 中风险过敏原标识 |
| 低风险 | Green | 低风险过敏原标识 |
| 安全 | Green | 无过敏原食物标识 |
| 危险 | Red | 含过敏原食物标识 |
4.2 过敏原类型样式
4.2.1 类型筛选条
┌─────────────────────────────────────────────────────────────┐
│ [全部] [🥛牛奶] [🥚鸡蛋] [🥜花生] [🌰坚果] [🐟鱼类] ... │
└─────────────────────────────────────────────────────────────┘
4.2.2 风险等级标签
| 等级 | 颜色 | 说明 |
|---|---|---|
| 高风险 | 红色 | 可能引发严重过敏反应 |
| 中风险 | 橙色 | 需要注意过敏风险 |
| 低风险 | 绿色 | 过敏反应相对轻微 |
4.3 组件规范
4.3.1 过敏原卡片
┌─────────────────────────────────────────────────────────────┐
│ ┌────┐ 牛奶过敏 > │
│ │ 🥛 │ [高风险] 牛奶 │
│ └────┘ │
│ 牛奶过敏是常见的食物过敏之一,主要由牛奶中的蛋白质引起... │
│ │
│ [牛奶] [奶粉] [奶油] [黄油] │
└─────────────────────────────────────────────────────────────┘
4.3.2 食物卡片
┌─────────────────────────┐
│ 🥛 │
│ 牛奶 │
│ 乳制品 │
│ │
│ ⚠️ 含过敏原 │
└─────────────────────────┘
4.3.3 食物详情弹窗
┌─────────────────────────────────────────┐
│ 🥛 牛奶 [×] │
├─────────────────────────────────────────┤
│ 分类: 乳制品 │
│ │
│ 含过敏原: │
│ [🥛 牛奶] │
└─────────────────────────────────────────┘
4.4 交互设计
4.4.1 操作方式
| 操作 | 手势 | 效果 |
|---|---|---|
| 查看过敏原详情 | 点击卡片 | 跳转详情页 |
| 查看食物详情 | 点击卡片 | 弹出详情弹窗 |
| 切换Tab | 点击底部导航 | 切换过敏原/食物 |
| 筛选类型 | 点击FilterChip | 按类型过滤 |
| 搜索 | 输入关键词 | 实时过滤 |
五、核心功能实现
5.1 主页面构建
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('过敏原查询'),
actions: [
PopupMenuButton<AllergenType?>(
icon: const Icon(Icons.filter_list),
onSelected: (value) {
setState(() {
_selectedType = value;
});
},
itemBuilder: (context) => [
const PopupMenuItem(value: null, child: Text('全部类型')),
...AllergenType.values.map((type) => PopupMenuItem(
value: type,
child: Text(typeEmoji + ' ' + typeName),
)),
],
),
],
),
body: Column(
children: [
_buildTypeChips(),
_buildSearchBar(),
Expanded(
child: _currentIndex == 0
? _buildAllergensList()
: _buildFoodsList(),
),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.warning_amber), label: '过敏原'),
BottomNavigationBarItem(icon: Icon(Icons.restaurant), label: '食物查询'),
],
),
);
}
5.2 过敏原卡片
Widget _buildAllergenCard(Allergen allergen) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: allergen.levelColor.withValues(alpha: 0.5)),
),
child: InkWell(
onTap: () => _showAllergenDetail(allergen),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
children: [
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: allergen.typeColor.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(12),
),
child: Text(allergen.typeEmoji, style: const TextStyle(fontSize: 28)),
),
// 名称、风险等级、类型
],
),
// 描述、食物标签
],
),
),
),
);
}
5.3 食物卡片
Widget _buildFoodCard(FoodItem food) {
final hasAllergen = food.allergens.isNotEmpty;
final mainColor = hasAllergen ? Colors.red : Colors.green;
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: mainColor.withValues(alpha: 0.3)),
),
child: InkWell(
onTap: () => _showFoodDetail(food),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(food.emoji, style: const TextStyle(fontSize: 36)),
Text(food.name, style: const TextStyle(fontWeight: FontWeight.bold)),
Text(food.category, style: TextStyle(fontSize: 12, color: Colors.grey)),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(color: mainColor.withValues(alpha: 0.1)),
child: Text(hasAllergen ? '含过敏原' : '安全'),
),
],
),
),
);
}
5.4 详情页面
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(allergen.name)),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// 过敏原基本信息卡片
_buildSection('过敏说明', allergen.description, ...),
_buildListSection('过敏症状', allergen.symptoms, ...),
_buildListSection('常见食物', allergen.foods, ...),
_buildListSection('隐藏来源', allergen.hiddenFoods, ...),
_buildListSection('替代食物', allergen.alternatives, ...),
_buildSection('预防建议', allergen.prevention, ...),
],
),
),
);
}
六、过敏原知识拓展
6.1 八大过敏原概述
6.2 过敏反应类型
| 反应类型 | 症状表现 | 严重程度 |
|---|---|---|
| 皮肤反应 | 皮疹、荨麻疹、瘙痒 | 轻至中度 |
| 呼吸道反应 | 打喷嚏、鼻塞、哮喘 | 中度 |
| 消化道反应 | 恶心、呕吐、腹泻 | 轻至中度 |
| 心血管反应 | 心跳加速、血压下降 | 重度 |
| 过敏性休克 | 多系统反应、危及生命 | 危重 |
6.3 过敏原隐藏来源
6.4 替代食物推荐
| 过敏原 | 替代食物 | 营养价值 |
|---|---|---|
| 牛奶 | 豆奶、杏仁奶、燕麦奶 | 植物蛋白、钙强化 |
| 鸡蛋 | 亚麻籽粉、香蕉泥 | 烘焙替代品 |
| 花生 | 葵花籽酱、芝麻酱 | 健康脂肪 |
| 小麦 | 大米、玉米、藜麦 | 无麸质谷物 |
| 大豆 | 其他豆类、牛奶 | 蛋白质来源 |
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 用户管理
| 功能 | 说明 |
|---|---|
| 过敏档案 | 记录个人过敏情况 |
| 家人管理 | 管理家庭成员过敏信息 |
| 紧急联系人 | 设置紧急求助联系人 |
7.2.2 智能功能
| 功能 | 说明 |
|---|---|
| 扫码查询 | 扫描食品条码查询过敏原 |
| AI识别 | 拍照识别食物成分 |
| 智能提醒 | 根据过敏档案自动提醒 |
7.2.3 社交功能
| 功能 | 说明 |
|---|---|
| 社区分享 | 分享过敏经验和替代食谱 |
| 餐厅推荐 | 推荐过敏友好的餐厅 |
| 紧急求助 | 一键发送求助信息 |
八、注意事项
8.1 开发注意事项
-
颜色处理:使用
withValues(alpha:)替代已废弃的withOpacity() -
风险等级判断:根据过敏原严重程度设置风险等级
-
食物安全标识:根据过敏原列表是否为空判断安全性
-
Tab切换:切换Tab时清空筛选条件
8.2 用户体验优化
💡 用户体验建议 💡
- 过敏原类型一目了然
- 风险等级清晰标识
- 食物安全状态明确
- 详情信息完整全面
8.3 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 食物卡片颜色错误 | hasAllergen判断错误 | 检查allergens列表 |
| 筛选无结果 | 过滤条件错误 | 检查筛选逻辑 |
| 风险等级不显示 | levelColor获取错误 | 检查level属性 |
| Tab切换异常 | 状态未重置 | 切换时清空筛选条件 |
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_allergen.dart
# 运行到Windows
flutter run -d windows -t lib/main_allergen.dart
# 代码分析
flutter analyze lib/main_allergen.dart
十、总结
过敏原查询应用通过完善的功能设计,帮助用户了解食物过敏的相关知识。应用涵盖八大常见过敏原,每种过敏原都有详细的症状说明、常见食物、隐藏来源和替代食物推荐,为过敏人群提供全面的参考信息。
食物查询功能让用户快速了解食物是否含有过敏原,安全/危险标识清晰明了。风险等级分级让用户了解不同过敏原的严重程度,高/中/低三级分类便于识别。详情页面信息完整,包含过敏说明、症状列表、食物来源、替代建议和预防措施。
界面设计采用红色主题风格,体现过敏警示的重要性。过敏原卡片边框颜色与风险等级对应,食物卡片颜色与安全状态对应,视觉层次分明。应用采用Material Design 3设计规范,遵循Flutter最佳实践,代码结构清晰,易于维护和扩展。
科学认知过敏原,安全饮食每一天!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)