import 'package:flutter/material.dart'; import 'package:food_hub_app/apis/recipe.dart'; import 'package:food_hub_app/models/recipe.dart'; import 'package:food_hub_app/utils/screenshot_util.dart'; import 'package:food_hub_app/widgets/common/index.dart'; class RecipeDetailPage extends StatefulWidget { const RecipeDetailPage({super.key}); @override State createState() => _RecipeDetailState(); } class _RecipeDetailState extends State { RecipeDetail recipe = RecipeDetail.getEmpty(); final GlobalKey _recipeDetailKey = GlobalKey(); bool _isSharing = false; // 定义三个分类列表 List mainMaterialList = []; // 主料 List auxiliaryMaterialList = []; // 配料 List accessoryMaterialList = []; // 辅料 @override void didChangeDependencies() { super.didChangeDependencies(); refreshRecipeDetail(); } Future refreshRecipeDetail() async { // 获取参数 final args = ModalRoute.of(context)?.settings.arguments as Map; final result = await queryRecipeByIdApi(args['id']); setState(() { recipe = result; getRecipeMaterial(); }); } void getRecipeMaterial() { mainMaterialList.clear(); auxiliaryMaterialList.clear(); accessoryMaterialList.clear(); for (var material in recipe.materialList) { switch (material.type) { case '主料': mainMaterialList.add(material); break; case '配料': auxiliaryMaterialList.add(material); break; case '辅料': accessoryMaterialList.add(material); break; } } } // 分享图片 Future _shareRecipeAsImage() async { if (_isSharing) return; setState(() { _isSharing = true; }); final timestamp = DateTime.now().millisecondsSinceEpoch; final imageName = '${recipe.name}_$timestamp.png'; await ScreenshotUtil.captureAndShare( globalKey: _recipeDetailKey, fileName: imageName, shareText: '分享菜谱: ${recipe.name}', ); setState(() { _isSharing = false; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('菜谱信息')), body: SingleChildScrollView( child: Column( children: [ // 用RepaintBoundary包裹要截图的部分 RepaintBoundary( key: _recipeDetailKey, child: Padding( padding: EdgeInsets.all(10), child: _buildRecipeDetail(), ), ), _buildButtons(), ], ), ), ); } Widget _buildRecipeDetail() { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ _buildTitleSection(), SizedBox(height: 8), _buildInfoCard( context, icon: Icons.info, title: "基础信息", content: buildTag(context, recipe.category), ), SizedBox(height: 8), _buildInfoCard( context, icon: Icons.shopping_cart, title: "食材信息", content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildMaterialSection(context, '主料', mainMaterialList), _buildMaterialSection(context, '辅料', auxiliaryMaterialList), _buildMaterialSection(context, '调料', accessoryMaterialList), ], ), ), SizedBox(height: 8), _buildInfoCard( context, icon: Icons.list, title: "步骤信息", content: Column( children: recipe.stepList.map((step) => _buildStepSection(step)).toList(), ), ), SizedBox(height: 8), _buildInfoCard( context, icon: Icons.note, title: "其他信息", content: Text( '备注:${recipe.remark.isEmpty ? '无' : recipe.remark}', style: const TextStyle(height: 1.5), ), ), ], ); } Widget _buildTitleSection() { return Text( recipe.name, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ); } Widget _buildMaterialSection( BuildContext context, String title, List materials, ) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(bottom: 8, top: 12), child: Text(title, style: TextStyle(fontWeight: FontWeight.bold)), ), if (materials.isEmpty) buildTag(context, '无') else Wrap( spacing: 8.0, runSpacing: 8.0, children: materials .map((m) => buildTag(context, '${m.name} ${m.amount}')) .toList(), ), ], ); } Widget _buildStepSection(RecipeStep step) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("第${step.sort + 1}步"), 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 _buildInfoCard( BuildContext context, { required IconData icon, required String title, required Widget content, }) { return BuildCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: Theme.of(context).colorScheme.primary), const SizedBox(width: 5), Text( title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), SizedBox(height: 5), content, ], ), ); } Widget _buildButtons() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ circleIconButton( context: context, icon: _isSharing ? Icons.hourglass_top : Icons.share, onPressed: _shareRecipeAsImage, ), ], ); } }