import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'ix_image.dart'; /// 国旗/图标组件 /// /// 智能查找逻辑: /// 1. 优先从 assets/flags/{countryCode}.svg 查找 /// 2. 找不到则从 assets/images/streaming/{countryCode}.png 查找 /// 3. 都找不到则显示默认图标 assets/flags/xx.svg class CountryIcon extends StatefulWidget { /// 国家/地区代码(如: us, cn, netflix 等) final String countryCode; /// 宽度 final double width; /// 高度 final double height; /// 圆角 final double? borderRadius; /// 适配方式 final BoxFit? fit; const CountryIcon({ super.key, required this.countryCode, required this.width, required this.height, this.borderRadius, this.fit, }); @override State createState() => _CountryIconState(); } class _CountryIconState extends State { /// 图片路径 String? _imagePath; /// 图片类型:svg 或 png String? _imageType; /// 是否正在加载 bool _isLoading = true; @override void initState() { super.initState(); _findImage(); } @override void didUpdateWidget(CountryIcon oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.countryCode != widget.countryCode) { _findImage(); } } /// 智能查找图片 Future _findImage() async { if (!mounted) return; setState(() { _isLoading = true; }); final code = widget.countryCode.toLowerCase().trim(); // 如果为空,直接使用默认图标 if (code.isEmpty) { setState(() { _imagePath = 'assets/flags/xx.svg'; _imageType = 'svg'; _isLoading = false; }); return; } // 1. 先检查 flags 目录的 svg final flagPath = 'assets/flags/$code.svg'; if (await _assetExists(flagPath)) { setState(() { _imagePath = flagPath; _imageType = 'svg'; _isLoading = false; }); return; } // 2. 检查 streaming 目录的 png final streamingPath = 'assets/images/streaming/$code.png'; if (await _assetExists(streamingPath)) { setState(() { _imagePath = streamingPath; _imageType = 'png'; _isLoading = false; }); return; } // 3. 使用默认图标 setState(() { _imagePath = 'assets/flags/xx.svg'; _imageType = 'svg'; _isLoading = false; }); } /// 检查资源文件是否存在 Future _assetExists(String path) async { try { await rootBundle.load(path); return true; } catch (e) { return false; } } @override Widget build(BuildContext context) { // 加载中显示占位符 if (_isLoading || _imagePath == null || _imageType == null) { return _buildPlaceholder(); } // 根据图片类型返回不同的组件 if (_imageType == 'svg') { return ClipRRect( borderRadius: BorderRadius.circular(widget.borderRadius ?? 0), child: SvgPicture.asset( _imagePath!, width: widget.width, height: widget.height, fit: widget.fit ?? BoxFit.cover, placeholderBuilder: (context) => _buildPlaceholder(), ), ); } else { // png 类型使用 IXImage return IXImage( source: _imagePath!, sourceType: ImageSourceType.asset, width: widget.width, height: widget.height, borderRadius: widget.borderRadius, fit: widget.fit, ); } } /// 构建占位符 Widget _buildPlaceholder() { return Container( width: widget.width, height: widget.height, decoration: BoxDecoration( color: Colors.grey.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(widget.borderRadius ?? 0), ), ); } } /// 国旗/图标组件的简化版本(同步加载,不检查文件是否存在) /// /// 性能更好,但可能在资源不存在时显示错误 class CountryIconFast extends StatelessWidget { /// 国家/地区代码 final String countryCode; /// 宽度 final double width; /// 高度 final double height; /// 圆角 final double? borderRadius; /// 适配方式 final BoxFit? fit; /// 是否优先使用 streaming 目录 final bool preferStreaming; const CountryIconFast({ Key? key, required this.countryCode, required this.width, required this.height, this.borderRadius, this.fit, this.preferStreaming = false, }) : super(key: key); @override Widget build(BuildContext context) { final code = countryCode.toLowerCase().trim(); if (code.isEmpty) { return _buildSvg('assets/flags/xx.svg'); } // 如果优先使用 streaming if (preferStreaming) { return _buildPng('assets/images/streaming/$code.png'); } // 默认优先使用 flags return _buildSvg('assets/flags/$code.svg'); } Widget _buildSvg(String path) { return ClipRRect( borderRadius: BorderRadius.circular(borderRadius ?? 0), child: SvgPicture.asset( path, width: width, height: height, fit: fit ?? BoxFit.cover, placeholderBuilder: (context) => _buildFallback(), ), ); } Widget _buildPng(String path) { return IXImage( source: path, sourceType: ImageSourceType.asset, width: width, height: height, borderRadius: borderRadius, fit: fit, ); } Widget _buildFallback() { // 降级到默认图标 return SvgPicture.asset( 'assets/flags/xx.svg', width: width, height: height, fit: fit ?? BoxFit.cover, ); } }