欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260405114622198

image-20260405114630456

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20260405114649065

1.1 应用简介

食材搭配是一款专注于食材营养搭配与健康饮食指导的移动应用,为用户提供科学的食材搭配建议。中华饮食文化讲究"药食同源",食材之间的搭配不仅影响口感,更关乎营养吸收与身体健康。本应用帮助用户了解食材搭配的奥秘,让每一餐都吃得健康、吃得科学。

应用支持八大食材分类,涵盖肉类、蔬菜、海鲜、水果、谷物、调味品、乳制品及其他。每种搭配都有详细的说明、推荐菜谱和营养标签,帮助用户做出明智的食材选择。黄金搭配、可以搭配、不宜搭配三种类型,让用户一目了然。

1.2 核心功能

功能模块 功能描述 实现方式
搭配列表 展示所有食材搭配,按类型排序 ListView + Card
分类筛选 八大食材分类快速筛选 FilterChip
类型筛选 黄金搭配/可以搭配/不宜搭配 PopupMenuButton
搜索功能 按食材名称、搭配说明搜索 TextField过滤
搭配详情 完整展示搭配说明、菜谱、营养 ModalBottomSheet
统计展示 各类型搭配数量统计 统计栏
食材信息 食材营养、功效介绍 信息卡片

1.3 食材搭配记录字段

字段 类型 说明
搭配ID String 唯一标识
食材1 Ingredient 第一种食材
食材2 Ingredient 第二种食材
搭配类型 PairingType 黄金/可以/不宜
搭配说明 String 搭配原因说明
推荐菜谱 String? 推荐菜品名称
标签列表 List 分类标签

1.4 食材记录字段

字段 类型 说明
食材ID String 唯一标识
食材名称 String 食材名称
食材分类 IngredientCategory 八大分类
食材描述 String 简要描述
营养成分 List 主要营养素
食疗功效 String 健康功效
表情符号 String 食材图标

1.5 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
状态管理 setState -
目标平台 鸿蒙OS API 21+

1.6 项目结构

lib/
└── main_ingredient_pairing.dart
    ├── IngredientPairingApp     # 应用入口
    ├── IngredientCategory       # 食材分类枚举
    ├── PairingType              # 搭配类型枚举
    ├── Ingredient               # 食材数据模型
    ├── IngredientPairing        # 搭配数据模型
    └── IngredientPairingPage    # 主页面
        ├── _buildCategoryChips()    # 分类筛选条
        ├── _buildSearchBar()        # 搜索栏
        ├── _buildStatisticsBar()    # 统计栏
        ├── _buildPairingsList()     # 搭配列表
        ├── _buildPairingCard()      # 搭配卡片
        ├── _showPairingDetail()     # 详情弹窗
        ├── _buildIngredientCircle() # 食材圆形展示
        └── _buildIngredientInfoCard() # 食材信息卡片

二、系统架构

2.1 整体架构图

Data Layer

Business Logic

Presentation Layer

主页面

分类筛选条

搜索栏

统计栏

搭配卡片列表

详情弹窗

食材展示区

搭配说明区

食材信息区

搭配筛选
分类/类型/搜索

排序逻辑
黄金>可以>不宜

详情展示
ModalBottomSheet

Ingredient
食材模型

IngredientPairing
搭配模型

IngredientCategory
分类枚举

PairingType
类型枚举

2.2 类图设计

contains

manages

manages

has

contains

has

IngredientPairingApp

+Widget build()

«enumeration»

IngredientCategory

meat

vegetable

seafood

fruit

grain

spice

dairy

other

«enumeration»

PairingType

good

neutral

bad

Ingredient

+String id

+String name

+IngredientCategory category

+String description

+List<String> nutrients

+String benefits

+String emoji

+String categoryName

+Color categoryColor

IngredientPairing

+String id

+Ingredient ingredient1

+Ingredient ingredient2

+PairingType type

+String reason

+String? recipe

+List<String> tags

+String typeText

+Color typeColor

+String typeEmoji

IngredientPairingPage

-List<Ingredient> _ingredients

-List<IngredientPairing> _pairings

-String _searchQuery

-IngredientCategory? _selectedCategory

-PairingType? _selectedPairingType

-List<IngredientPairing> _filteredPairings

+Widget build()

-void _showPairingDetail()

2.3 数据流程图

筛选分类

筛选类型

搜索

查看详情

用户操作

操作类型

按食材分类过滤

按搭配类型过滤

关键词匹配过滤

弹出详情弹窗

更新搭配列表

展示食材信息

展示搭配说明

展示推荐菜谱

2.4 搭配详情展示流程

数据模型 详情弹窗 主页面 用户 数据模型 详情弹窗 主页面 用户 点击搭配卡片 showModalBottomSheet 展示食材圆形图标 展示搭配类型标签 展示搭配说明 展示推荐菜谱 展示食材营养信息 下滑关闭 返回主页面

三、核心模块设计

3.1 数据模型设计

3.1.1 食材分类枚举 (IngredientCategory)
enum IngredientCategory {
  meat,      // 肉类
  vegetable, // 蔬菜
  seafood,   // 海鲜
  fruit,     // 水果
  grain,     // 谷物
  spice,     // 调味品
  dairy,     // 乳制品
  other,     // 其他
}
3.1.2 食材分类属性映射
分类类型 中文名称 主题颜色
meat 肉类 红色
vegetable 蔬菜 绿色
seafood 海鲜 蓝色
fruit 水果 橙色
grain 谷物 琥珀色
spice 调味品 紫色
dairy 乳制品 青色
other 其他 灰色
3.1.3 搭配类型枚举 (PairingType)
enum PairingType {
  good,    // 黄金搭配
  neutral, // 可以搭配
  bad,     // 不宜搭配
}
3.1.4 搭配类型属性映射
搭配类型 中文名称 表情符号 主题颜色
good 黄金搭配 绿色
neutral 可以搭配 ⚠️ 橙色
bad 不宜搭配 红色
3.1.5 食材模型 (Ingredient)
class Ingredient {
  final String id;                  // 唯一标识
  final String name;                // 食材名称
  final IngredientCategory category; // 食材分类
  final String description;         // 食材描述
  final List<String> nutrients;     // 营养成分
  final String benefits;            // 食疗功效
  final String emoji;               // 表情符号

  String get categoryName;          // 分类中文名
  Color get categoryColor;          // 分类主题色
}
3.1.6 搭配模型 (IngredientPairing)
class IngredientPairing {
  final String id;                  // 唯一标识
  final Ingredient ingredient1;     // 食材1
  final Ingredient ingredient2;     // 食材2
  final PairingType type;           // 搭配类型
  final String reason;              // 搭配说明
  final String? recipe;             // 推荐菜谱
  final List<String> tags;          // 标签列表

  String get typeText;              // 类型中文名
  Color get typeColor;              // 类型主题色
  String get typeEmoji;             // 类型表情
}

3.2 筛选过滤算法

3.2.1 过滤流程

获取全部搭配

是否选择类型?

按搭配类型过滤

是否选择分类?

按食材分类过滤

是否有搜索词?

关键词匹配过滤

按类型排序

返回过滤结果

3.2.2 过滤实现
List<IngredientPairing> get _filteredPairings {
  var pairings = _pairings.toList();

  // 搭配类型筛选
  if (_selectedPairingType != null) {
    pairings = pairings.where((p) => p.type == _selectedPairingType).toList();
  }

  // 食材分类筛选
  if (_selectedCategory != null) {
    pairings = pairings.where((p) {
      return p.ingredient1.category == _selectedCategory ||
          p.ingredient2.category == _selectedCategory;
    }).toList();
  }

  // 关键词搜索
  if (_searchQuery.isNotEmpty) {
    pairings = pairings.where((p) {
      return p.ingredient1.name.contains(_searchQuery) ||
          p.ingredient2.name.contains(_searchQuery) ||
          p.reason.contains(_searchQuery) ||
          p.tags.any((tag) => tag.contains(_searchQuery));
    }).toList();
  }

  // 按类型排序:黄金 > 可以 > 不宜
  pairings.sort((a, b) {
    final order = {PairingType.good: 0, PairingType.neutral: 1, PairingType.bad: 2};
    return order[a.type]!.compareTo(order[b.type]!);
  });

  return pairings;
}

3.3 详情弹窗设计

3.3.1 弹窗结构

详情弹窗

顶部拖拽条

食材展示区

搭配说明区

推荐菜谱区

标签展示区

食材信息区

食材1圆形图标

搭配类型标签

食材2圆形图标

食材1信息卡片

食材2信息卡片

3.3.2 弹窗实现
void _showPairingDetail(IngredientPairing pairing) {
  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
    ),
    builder: (context) {
      return DraggableScrollableSheet(
        initialChildSize: 0.6,
        minChildSize: 0.4,
        maxChildSize: 0.9,
        expand: false,
        builder: (context, scrollController) {
          return SingleChildScrollView(
            controller: scrollController,
            child: Column(
              children: [
                // 食材展示区
                // 搭配说明区
                // 推荐菜谱区
                // 食材信息区
              ],
            ),
          );
        },
      );
    },
  );
}

3.4 页面结构设计

3.4.1 主页面布局

主页面

AppBar

分类筛选条

搜索栏

统计栏

搭配卡片列表

标题: 食材搭配

类型筛选菜单

FilterChip: 全部

FilterChip: 肉类

FilterChip: 蔬菜

...

黄金搭配统计

可以搭配统计

不宜搭配统计

搭配卡片1

搭配卡片2

...

3.5 状态管理

3.5.1 核心状态变量
class _IngredientPairingPageState extends State<IngredientPairingPage> {
  final List<Ingredient> _ingredients = [];           // 所有食材
  final List<IngredientPairing> _pairings = [];       // 所有搭配
  String _searchQuery = '';                           // 搜索关键词
  IngredientCategory? _selectedCategory;              // 选中的分类筛选
  PairingType? _selectedPairingType;                  // 选中的类型筛选
}

四、UI设计规范

4.1 配色方案

应用采用绿色主题风格,体现健康饮食的理念:

颜色类型 色值 用途
主色 Green AppBar、按钮、强调
黄金搭配 Green 黄金搭配标识
可以搭配 Orange 可以搭配标识
不宜搭配 Red 不宜搭配标识
肉类 Red 肉类食材标识
蔬菜 Green 蔬菜食材标识
海鲜 Blue 海鲜食材标识

4.2 搭配类型样式

4.2.1 类型标签
类型 表情 颜色 说明
黄金搭配 绿色 营养互补,推荐搭配
可以搭配 ⚠️ 橙色 可以搭配,注意事项
不宜搭配 红色 不建议同食,影响健康
4.2.2 食材圆形图标
┌─────────────────┐
│   🥩            │  ← 食材表情
│                 │
│   彩色圆形背景   │  ← 分类对应颜色
│   彩色圆形边框   │
└─────────────────┘

4.3 组件规范

4.3.1 搭配卡片
┌─────────────────────────────────────────────────────────────┐
│  [🥩猪肉]  ✅ 黄金搭配  [🥬白菜]                            │
│                                                              │
│  猪肉与白菜搭配,荤素结合,营养均衡。白菜的清香可以...       │
│                                                              │
│  [经典搭配] [家常菜]                                         │
└─────────────────────────────────────────────────────────────┘
4.3.2 统计栏
┌─────────────────────────────────────────────────────────────┐
│  ✅ 黄金搭配      ⚠️ 可以搭配      ❌ 不宜搭配              │
│     8组              1组             3组                     │
└─────────────────────────────────────────────────────────────┘
4.3.3 详情弹窗
┌─────────────────────────────────────────────────────────────┐
│                        ───────                              │
│                                                             │
│       🥩          ✅              🥬                        │
│      猪肉     黄金搭配           白菜                       │
│               肉类               蔬菜                       │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ ℹ️ 搭配说明                                          │   │
│  │ 猪肉与白菜搭配,荤素结合,营养均衡...                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 🍴 推荐菜谱                                          │   │
│  │ 白菜炖猪肉、猪肉白菜饺子                              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  [经典搭配] [家常菜]                                        │
│                                                             │
│  ┌──────────────────┐  ┌──────────────────┐                │
│  │ 🥩 猪肉          │  │ 🥬 白菜          │                │
│  │ 常见肉类         │  │ 冬季当家菜       │                │
│  │ [蛋白质][脂肪]   │  │ [维生素C][膳食纤维]│               │
│  └──────────────────┘  └──────────────────┘                │
└─────────────────────────────────────────────────────────────┘

4.4 交互设计

4.4.1 操作方式
操作 手势 效果
查看详情 点击卡片 弹出详情弹窗
筛选分类 点击FilterChip 按食材分类过滤
筛选类型 点击筛选菜单 按搭配类型过滤
搜索 输入关键词 实时过滤
关闭详情 下滑/点击外部 关闭弹窗

五、核心功能实现

5.1 主页面构建


Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('食材搭配'),
      actions: [
        PopupMenuButton<PairingType?>(
          icon: const Icon(Icons.filter_list),
          onSelected: (value) {
            setState(() {
              _selectedPairingType = value;
            });
          },
          itemBuilder: (context) => [
            const PopupMenuItem(value: null, child: Text('全部类型')),
            const PopupMenuItem(value: PairingType.good, child: Text('✅ 黄金搭配')),
            const PopupMenuItem(value: PairingType.neutral, child: Text('⚠️ 可以搭配')),
            const PopupMenuItem(value: PairingType.bad, child: Text('❌ 不宜搭配')),
          ],
        ),
      ],
    ),
    body: Column(
      children: [
        _buildCategoryChips(),
        _buildSearchBar(),
        _buildStatisticsBar(),
        Expanded(
          child: _filteredPairings.isEmpty
              ? _buildEmptyState()
              : _buildPairingsList(),
        ),
      ],
    ),
  );
}

5.2 分类筛选条

Widget _buildCategoryChips() {
  return Container(
    height: 50,
    padding: const EdgeInsets.symmetric(horizontal: 8),
    child: ListView(
      scrollDirection: Axis.horizontal,
      children: [
        FilterChip(
          label: const Text('全部'),
          selected: _selectedCategory == null,
          onSelected: (selected) {
            setState(() {
              _selectedCategory = null;
            });
          },
        ),
        ...IngredientCategory.values.map((category) {
          return FilterChip(
            label: Text(categoryName),
            selected: _selectedCategory == category,
            selectedColor: categoryColor.withValues(alpha: 0.2),
            onSelected: (selected) {
              setState(() {
                _selectedCategory = selected ? category : null;
              });
            },
          );
        }),
      ],
    ),
  );
}

5.3 统计栏

Widget _buildStatisticsBar() {
  final goodCount = _pairings.where((p) => p.type == PairingType.good).length;
  final neutralCount = _pairings.where((p) => p.type == PairingType.neutral).length;
  final badCount = _pairings.where((p) => p.type == PairingType.bad).length;

  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
      _buildStatItem('✅', '黄金搭配', goodCount, Colors.green),
      _buildStatItem('⚠️', '可以搭配', neutralCount, Colors.orange),
      _buildStatItem('❌', '不宜搭配', badCount, Colors.red),
    ],
  );
}

5.4 详情弹窗

void _showPairingDetail(IngredientPairing pairing) {
  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    builder: (context) {
      return DraggableScrollableSheet(
        initialChildSize: 0.6,
        minChildSize: 0.4,
        maxChildSize: 0.9,
        expand: false,
        builder: (context, scrollController) {
          return SingleChildScrollView(
            controller: scrollController,
            child: Column(
              children: [
                // 食材展示区
                Row(
                  children: [
                    _buildIngredientCircle(pairing.ingredient1),
                    // 搭配类型标签
                    _buildIngredientCircle(pairing.ingredient2),
                  ],
                ),
                // 搭配说明区
                // 推荐菜谱区
                // 食材信息区
              ],
            ),
          );
        },
      );
    },
  );
}

5.5 食材圆形图标

Widget _buildIngredientCircle(Ingredient ingredient) {
  return Column(
    children: [
      Container(
        width: 80,
        height: 80,
        decoration: BoxDecoration(
          color: ingredient.categoryColor.withValues(alpha: 0.2),
          shape: BoxShape.circle,
          border: Border.all(
            color: ingredient.categoryColor,
            width: 2,
          ),
        ),
        child: Center(
          child: Text(ingredient.emoji, style: const TextStyle(fontSize: 36)),
        ),
      ),
      Text(ingredient.name, style: const TextStyle(fontWeight: FontWeight.bold)),
      Text(ingredient.categoryName, style: TextStyle(color: ingredient.categoryColor)),
    ],
  );
}

六、食材搭配知识拓展

6.1 食材搭配原则

食材搭配原则

营养互补

口味协调

功效协同

避免相克

蛋白质互补

维生素协同

矿物质平衡

荤素搭配

酸甜平衡

软硬适中

温凉调和

补泻兼顾

避免化学反应

避免营养抵消

6.2 常见食材相克

食材组合 相克原因 建议
菠菜 + 豆腐 草酸与钙形成草酸钙 菠菜焯水后可同食
螃蟹 + 柿子 形成胃结石 间隔2小时以上
虾 + 维C 可能产生砷化合物 避免大量同食
牛奶 + 柠檬 蛋白质凝固 分开食用
萝卜 + 人参 功效相抵 避免同食

6.3 黄金搭配推荐

食材组合 搭配优势 推荐菜品
猪肉 + 白菜 荤素搭配,营养均衡 白菜炖猪肉
西红柿 + 鸡蛋 蛋白质与番茄红素互补 西红柿炒蛋
牛肉 + 胡萝卜 脂溶性维生素更易吸收 胡萝卜炖牛肉
豆腐 + 鱼 动植物蛋白互补 鱼头豆腐汤
螃蟹 + 生姜 中和寒性,去腥增香 清蒸螃蟹配姜醋

6.4 食材分类营养特点

食材分类

肉类
蛋白质/铁/锌

蔬菜
维生素/膳食纤维

海鲜
优质蛋白/DHA

水果
维生素C/果糖

谷物
碳水化合物/B族

调味品
风味/微量元素

乳制品
钙/蛋白质


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 核心搭配功能 八大分类筛选 详情弹窗展示 数据持久化 自定义搭配添加 导入导出功能 营养计算功能 智能推荐系统 社区分享功能 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 食材搭配应用开发计划

7.2 功能扩展建议

7.2.1 数据管理
功能 说明
SQLite存储 本地数据库存储搭配数据
自定义添加 用户自定义食材搭配
数据同步 云端数据备份同步
7.2.2 智能功能
功能 说明
营养计算 计算搭配营养成分
智能推荐 根据食材推荐搭配
饮食建议 个性化饮食建议
7.2.3 社交功能
功能 说明
搭配分享 分享搭配到社交平台
用户评价 用户对搭配评分
社区讨论 食材搭配话题讨论

八、注意事项

8.1 开发注意事项

  1. 颜色处理:使用 withValues(alpha:) 替代已废弃的 withOpacity()

  2. 弹窗实现:使用 DraggableScrollableSheet 实现可拖拽弹窗

  3. 列表展开语法if (condition) ...[widgets] 正确使用展开操作符

  4. 筛选逻辑:分类筛选需检查两个食材是否都属于该分类

8.2 用户体验优化

💡 用户体验建议 💡

  • 分类筛选直观便捷
  • 搭配类型一目了然
  • 详情展示清晰完整
  • 弹窗交互流畅自然

8.3 常见问题

问题 原因 解决方案
弹窗无法拖拽 DraggableScrollableSheet配置错误 检查expand参数
筛选无结果 过滤条件错误 检查筛选逻辑
颜色不显示 颜色值错误 检查categoryColor getter
列表展开语法错误 ...[]使用不当 检查语法结构

九、运行说明

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_ingredient_pairing.dart

# 运行到Windows
flutter run -d windows -t lib/main_ingredient_pairing.dart

# 代码分析
flutter analyze lib/main_ingredient_pairing.dart

十、总结

食材搭配应用通过完善的功能设计,帮助用户了解食材搭配的科学知识。应用支持八大食材分类,配以专属主题色彩,让食材分类更加直观。黄金搭配、可以搭配、不宜搭配三种类型,让用户快速了解搭配建议。

详情弹窗采用可拖拽设计,展示食材圆形图标、搭配说明、推荐菜谱和食材营养信息,信息展示完整清晰。统计栏实时显示各类型搭配数量,让用户对数据一目了然。搜索和筛选功能让用户快速定位目标搭配。

界面设计采用绿色主题风格,体现健康饮食的理念。食材圆形图标设计美观大方,搭配卡片边框颜色与类型对应,视觉层次分明。应用采用Material Design 3设计规范,遵循Flutter最佳实践,代码结构清晰,易于维护和扩展。

科学搭配,健康饮食,营养均衡,美味生活!


Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐