feat: 支持食物详情弹窗
This commit is contained in:
@@ -1,109 +1,68 @@
|
||||
# 食物库弹窗组件
|
||||
# 食物库页面实现说明
|
||||
|
||||
## 功能概述
|
||||
## 概述
|
||||
|
||||
食物库弹窗组件 (`FoodLibraryModal`) 是一个完整的食物选择界面,用户可以通过分类浏览和搜索来选择食物。
|
||||
已成功将食物库从弹窗模式改造为页面模式,解决了React Native中Modal嵌套的问题。
|
||||
|
||||
## 主要特性
|
||||
## 实现内容
|
||||
|
||||
- ✅ 完全按照设计图还原的UI界面
|
||||
- ✅ 左侧分类导航,右侧食物列表
|
||||
- ✅ 搜索功能
|
||||
- ✅ 食物信息显示(名称、卡路里、单位)
|
||||
- ✅ 餐次选择(早餐、午餐、晚餐、加餐)
|
||||
- ✅ 自定义和收藏功能预留
|
||||
### 1. 创建食物库页面
|
||||
- **文件位置**: `app/food-library.tsx`
|
||||
- **功能**: 完整的食物库界面,包含搜索、分类导航、食物列表等功能
|
||||
- **特点**:
|
||||
- 支持URL参数传递餐次类型 (`mealType`)
|
||||
- 使用Expo Router进行页面导航
|
||||
- 在页面中可以正常使用FoodDetailModal弹窗
|
||||
|
||||
### 2. 修改营养卡片组件
|
||||
- **文件**: `components/NutritionRadarCard.tsx`
|
||||
- **修改内容**:
|
||||
- 移除了FoodLibraryModal的导入和使用
|
||||
- 将加号按钮的点击事件改为页面导航
|
||||
- 使用 `router.push('/food-library?mealType=${currentMealType}')` 进行导航
|
||||
|
||||
### 3. 更新路由配置
|
||||
- **文件**: `constants/Routes.ts`
|
||||
- **新增**: `FOOD_LIBRARY: '/food-library'` 路由常量
|
||||
|
||||
### 4. 清理旧文件
|
||||
- 删除了 `components/model/food/FoodLibraryModal.tsx`
|
||||
- 更新了 `components/model/food/index.ts` 导出文件
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 1. 在营养卡片中使用
|
||||
1. 在statistics页面的营养卡片中点击右上角的加号按钮
|
||||
2. 会导航到食物库页面 (`/food-library`)
|
||||
3. 在食物库页面中点击食物项的加号按钮
|
||||
4. 会弹出食物详情弹窗 (FoodDetailModal)
|
||||
5. 在详情弹窗中可以选择单位和数量,点击保存后返回statistics页面
|
||||
|
||||
在 `statistics.tsx` 页面的营养摄入分析卡片右上角,点击绿色的加号按钮即可打开食物库弹窗。
|
||||
## 技术优势
|
||||
|
||||
### 2. 组件集成
|
||||
1. **解决Modal嵌套问题**: 避免了React Native中Modal嵌套的兼容性问题
|
||||
2. **更好的用户体验**: 页面导航比弹窗更符合移动端的交互习惯
|
||||
3. **键盘适配**: FoodDetailModal中的键盘适配功能可以正常工作
|
||||
4. **代码结构清晰**: 页面和弹窗职责分离,代码更易维护
|
||||
|
||||
```tsx
|
||||
import { FoodLibraryModal, FoodItem } from '@/components/model/food/FoodLibraryModal';
|
||||
## 页面功能
|
||||
|
||||
// 在组件中使用
|
||||
const [showFoodLibrary, setShowFoodLibrary] = useState(false);
|
||||
### 食物库页面功能
|
||||
- ✅ 搜索食物
|
||||
- ✅ 分类导航(常见、自定义、收藏等)
|
||||
- ✅ 食物列表展示
|
||||
- ✅ 餐次显示
|
||||
- ✅ 返回导航
|
||||
|
||||
const handleSelectFood = (food: FoodItem) => {
|
||||
console.log('选择了食物:', food);
|
||||
// 处理食物选择逻辑
|
||||
};
|
||||
### 食物详情弹窗功能
|
||||
- ✅ 食物信息展示
|
||||
- ✅ 营养成分显示
|
||||
- ✅ 单位选择(克、小份、中份、大份)
|
||||
- ✅ 数量输入
|
||||
- ✅ 键盘适配
|
||||
- ✅ 保存功能
|
||||
|
||||
<FoodLibraryModal
|
||||
visible={showFoodLibrary}
|
||||
onClose={() => setShowFoodLibrary(false)}
|
||||
onSelectFood={handleSelectFood}
|
||||
mealType="breakfast"
|
||||
/>
|
||||
```
|
||||
## 注意事项
|
||||
|
||||
## 组件结构
|
||||
|
||||
```
|
||||
components/
|
||||
model/
|
||||
food/
|
||||
├── FoodLibraryModal.tsx # 主要弹窗组件
|
||||
└── index.ts # 导出文件
|
||||
```
|
||||
|
||||
## 数据结构
|
||||
|
||||
### FoodItem
|
||||
```tsx
|
||||
interface FoodItem {
|
||||
id: string;
|
||||
name: string;
|
||||
emoji: string;
|
||||
calories: number;
|
||||
unit: string; // 如 "100克"
|
||||
}
|
||||
```
|
||||
|
||||
### FoodCategory
|
||||
```tsx
|
||||
interface FoodCategory {
|
||||
id: string;
|
||||
name: string;
|
||||
foods: FoodItem[];
|
||||
}
|
||||
```
|
||||
|
||||
## 食物分类
|
||||
|
||||
- 常见
|
||||
- 自定义
|
||||
- 收藏
|
||||
- 水果蔬菜
|
||||
- 肉蛋奶
|
||||
- 豆类坚果
|
||||
- 零食饮料
|
||||
- 主食
|
||||
- 菜肴
|
||||
|
||||
## 已实现的功能
|
||||
|
||||
1. **分类浏览** - 左侧导航可切换不同食物分类
|
||||
2. **搜索功能** - 顶部搜索框支持食物名称搜索
|
||||
3. **食物选择** - 点击右侧加号按钮选择食物
|
||||
4. **餐次指示** - 底部显示当前餐次(早餐、午餐、晚餐、加餐)
|
||||
5. **UI动画** - 模态弹窗的滑入滑出动画
|
||||
|
||||
## 待扩展功能
|
||||
|
||||
1. **自定义食物** - 用户可以添加自定义食物
|
||||
2. **收藏功能** - 用户可以收藏常用食物
|
||||
3. **营养详情** - 显示更详细的营养成分信息
|
||||
4. **数据持久化** - 将选择的食物保存到营养记录中
|
||||
5. **餐次切换** - 底部餐次选择器的交互功能
|
||||
|
||||
## 技术实现
|
||||
|
||||
- 使用 React Native Modal 实现全屏弹窗
|
||||
- 使用 ScrollView 实现分类和食物列表的滚动
|
||||
- 使用 TouchableOpacity 实现交互反馈
|
||||
- 使用 Ionicons 图标库
|
||||
- 完全响应式设计,适配不同屏幕尺寸
|
||||
1. 食物库页面使用URL参数传递餐次类型,确保从不同餐次点击加号时能正确显示对应的餐次
|
||||
2. FoodDetailModal仍然是弹窗形式,但现在是在页面中使用,避免了嵌套问题
|
||||
3. 所有原有的UI样式和交互逻辑都得到了保留
|
||||
Reference in New Issue
Block a user