2026-04-07 03:39:20 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
2026-04-09 00:34:17 +08:00
|
|
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
2026-04-07 03:39:20 +08:00
|
|
|
|
|
|
|
|
|
|
/// 数字货币图标组件
|
2026-04-09 00:34:17 +08:00
|
|
|
|
///
|
|
|
|
|
|
/// 支持离线 SVG 图标和兜底显示
|
2026-04-07 03:39:20 +08:00
|
|
|
|
class CoinIcon extends StatelessWidget {
|
2026-04-09 00:34:17 +08:00
|
|
|
|
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<String, String> _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 = SvgPicture.asset(
|
|
|
|
|
|
'assets/icons/crypto/$fileName.svg',
|
|
|
|
|
|
width: size,
|
|
|
|
|
|
height: size,
|
|
|
|
|
|
fit: BoxFit.contain,
|
|
|
|
|
|
placeholderBuilder: (context) => _buildFallback(context, normalizedSymbol),
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
icon = _buildFallback(context, normalizedSymbol);
|
2026-04-07 03:39:20 +08:00
|
|
|
|
}
|
2026-04-09 00:34:17 +08:00
|
|
|
|
|
|
|
|
|
|
if (isCircle) {
|
|
|
|
|
|
return Container(
|
|
|
|
|
|
width: size,
|
|
|
|
|
|
height: size,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
shape: BoxShape.circle,
|
|
|
|
|
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
|
|
|
|
|
),
|
|
|
|
|
|
child: Center(child: icon),
|
|
|
|
|
|
);
|
2026-04-07 03:39:20 +08:00
|
|
|
|
}
|
2026-04-09 00:34:17 +08:00
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2026-04-07 03:39:20 +08:00
|
|
|
|
}
|