import 'package:flutter/material.dart'; import 'package:food_hub_app/models/recipe.dart' as recipeModel; class RecipeDetail extends StatefulWidget { const RecipeDetail({super.key}); @override State createState() => _RecipeDetailState(); } class _RecipeDetailState extends State { @override void initState() { super.initState(); } recipeModel.Recipe recipe = recipeModel.Recipe( name: '雪糕', category: '冷饮', recommendRate: 4, isShare: true, recordList: [], stepList: [ recipeModel.Step( sort: 1, content: '将牛奶倒入锅中,小火加热至微沸', imageUrl: 'https://picsum.photos/400/300?step=1', // 步骤图片URL ), recipeModel.Step(sort: 2, content: '你好', imageUrl: ''), ], materialList: [], ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('菜谱信息', style: TextStyle(color: Colors.white)), backgroundColor: Theme.of(context).primaryColor, leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.pop(context), ), ), backgroundColor: Color(0xFFF5F5F5), body: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(5), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( recipe.name, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), // 基础信息卡片 _buildInfoCard( context, icon: Icons.info, title: "基础信息", content: Column( children: [_buildInfoRow("类别", recipe.category)], ), ), // 食材信息卡片 _buildInfoCard( context, icon: Icons.shopping_cart, title: "食材信息", content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildMaterialSection("主料", 1), _buildMaterialSection("配料", 2), _buildMaterialSection("辅料", 3), ], ), ), // 步骤信息卡片 _buildInfoCard( context, icon: Icons.list, title: "步骤信息", content: Column( children: recipe.stepList?.map((step) { return _buildStepSection(step); }).toList() ?? [], ), ), // 其他信息卡片 if (recipe.remark != null && recipe.remark!.isNotEmpty) _buildInfoCard( context, icon: Icons.note, title: "其他信息", content: Text( recipe.remark!, style: const TextStyle(height: 1.5), ), ), const SizedBox(height: 20), ], ), ), ), ); } // 构建食材分类部分 Widget _buildMaterialSection(String title, int type) { final materials = recipe.materialList ?.where((material) => material.type == type) ?.toList() ?? []; if (materials.isEmpty) return const SizedBox.shrink(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text( title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), ), ...materials.map((material) { return Padding( padding: const EdgeInsets.only(bottom: 4.0), child: Row( children: [ const Icon(Icons.circle, size: 6, color: Colors.grey), const SizedBox(width: 8), Text("${material.name} ${material.amount ?? ''}"), ], ), ); }).toList(), ], ); } Widget _buildStepSection(recipeModel.Step step) { return Padding( padding: const EdgeInsets.only(bottom: 16.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("第${step.sort}步"), SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(step.content, style: const TextStyle(height: 1.4, fontWeight: FontWeight.bold)), const SizedBox(height: 8), if (step.imageUrl.isNotEmpty) ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( step.imageUrl, width: double.infinity, height: 180, fit: BoxFit.contain, ), ), ], ), ), ], ), ); } // 构建信息行 Widget _buildInfoRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text(label), Text(value)], ), ); } // 通用卡片组件 Widget _buildInfoCard( BuildContext context, { required IconData icon, required String title, required Widget content, }) { return Card( elevation: 0, color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), child: Padding( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: Theme.of(context).primaryColor), const SizedBox(width: 8), Text( title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), SizedBox(height: 5), content, ], ), ), ); } }