import 'package:flutter/material.dart'; /// 数字货币图标组件 /// /// 支持离线图标和兜底显示 class CoinIcon extends StatelessWidget { final String symbol; // 币种代码,如 'BTC', 'ETH' final double size; // 图标大小,默认 40 final bool isCircle; // 是否圆形背景,默认 false const CoinIcon({ super.key, required this.symbol, this.size = 40, this.isCircle = false, }); // 币种代码到文件名的映射 static const Map _coinFileMap = { 'BTC': 'btc', 'ETH': 'eth', 'USDT': 'usdt', 'BNB': 'bnb', 'SOL': 'sol', 'XRP': 'xrp', 'ADA': 'ada', 'DOGE': 'doge', 'DOT': 'dot', 'MATIC': 'matic', 'SHIB': 'shib', 'LTC': 'ltc', 'AVAX': 'avax', 'LINK': 'link', 'UNI': 'uni', 'ATOM': 'atom', }; @override Widget build(BuildContext context) { final normalizedSymbol = symbol.toUpperCase(); final fileName = _coinFileMap[normalizedSymbol]; Widget icon; if (fileName != null) { // 尝试加载本地图标 icon = Image.asset( 'assets/icons/crypto/$fileName.png', width: size, height: size, fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { // 加载失败,显示兜底UI return _buildFallback(context, normalizedSymbol); }, ); } else { // 没有对应的图标,显示兜底UI icon = _buildFallback(context, normalizedSymbol); } if (isCircle) { return Container( width: size, height: size, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.surfaceContainerHigh, ), child: Center(child: icon), ); } return icon; } /// 构建兜底UI(显示币种代码) Widget _buildFallback(BuildContext context, String symbol) { return Container( width: size, height: size, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Theme.of(context).colorScheme.primary, Theme.of(context).colorScheme.secondary, ], ), ), child: Center( child: Text( symbol.length > 3 ? symbol.substring(0, 3) : symbol, style: TextStyle( color: Colors.white, fontSize: size * 0.35, fontWeight: FontWeight.bold, ), ), ), ); } }