import 'dart:io'; import 'package:flutter/material.dart'; import 'package:camera_app/services/yolo_service.dart'; class ResultScreen extends StatefulWidget { final List photoPaths; final Map analysisResults; const ResultScreen({ super.key, required this.photoPaths, required this.analysisResults, }); @override State createState() => _ResultScreenState(); } class _ResultScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: const Text('分析结果'), backgroundColor: Colors.blue.shade700, foregroundColor: Colors.white, elevation: 0, ), body: Column( children: [ // 统计信息卡片 Container( width: double.infinity, margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.blue.shade200), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.photo_library, color: Colors.blue.shade700), const SizedBox(width: 8), Text( '共拍摄 ${widget.photoPaths.length} 张照片', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade900, ), ), ], ), const SizedBox(height: 12), Text( '已分析 ${widget.analysisResults.length} 张', style: TextStyle( fontSize: 14, color: Colors.blue.shade700, ), ), ], ), ), // 分析结果列表 Expanded( child: widget.analysisResults.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.info_outline, size: 64, color: Colors.grey.shade400, ), const SizedBox(height: 16), Text( '暂无分析结果', style: TextStyle( fontSize: 18, color: Colors.grey.shade600, ), ), ], ), ) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: widget.photoPaths.length, itemBuilder: (context, index) { final photoPath = widget.photoPaths[index]; final result = widget.analysisResults[photoPath]; return _buildPhotoAnalysisCard(photoPath, result, index); }, ), ), // 完成按钮 Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, -2), ), ], ), child: ElevatedButton( onPressed: () { // 返回欢迎页面 Navigator.of(context).popUntil((route) => route.isFirst); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue.shade700, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text( '完成', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), ], ), ); } Widget _buildPhotoAnalysisCard( String photoPath, YOLOAnalysisResult? result, int index, ) { return Card( margin: const EdgeInsets.only(bottom: 16), elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 图片预览 ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(12)), child: Image.file( File(photoPath), width: double.infinity, height: 200, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( width: double.infinity, height: 200, color: Colors.grey.shade200, child: const Icon(Icons.broken_image, size: 64), ); }, ), ), // 分析结果 Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.image, color: Colors.blue.shade700), const SizedBox(width: 8), Text( '照片 ${index + 1}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey.shade800, ), ), ], ), const SizedBox(height: 12), if (result == null) const Text( '分析中...', style: TextStyle(color: Colors.grey), ) else if (result.error != null) Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.orange.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.orange.shade200), ), child: Row( children: [ Icon(Icons.warning, color: Colors.orange.shade700), const SizedBox(width: 8), Expanded( child: Text( result.error!, style: TextStyle(color: Colors.orange.shade900), ), ), ], ), ) else if (result.objects.isEmpty) const Text( '未检测到物体', style: TextStyle(color: Colors.grey), ) else Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '检测到 ${result.objects.length} 个物体:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey.shade700, ), ), const SizedBox(height: 8), ...result.objects.map((obj) => Padding( padding: const EdgeInsets.only(bottom: 8), child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.green.shade200), ), child: Row( children: [ Icon(Icons.label, color: Colors.green.shade700), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( obj.label, style: TextStyle( fontWeight: FontWeight.bold, color: Colors.green.shade900, ), ), Text( '置信度: ${(obj.confidence * 100).toStringAsFixed(1)}%', style: TextStyle( fontSize: 12, color: Colors.green.shade700, ), ), ], ), ), ], ), ), )), ], ), ], ), ), ], ), ); } }