Files
monisuo/flutter_monisuo/lib/ui/pages/trade/components/price_card.dart
2026-04-21 08:09:45 +08:00

131 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../core/theme/app_spacing.dart';
import '../../../../data/models/coin.dart';
import '../../../components/coin_icon.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
/// 交易页顶部信息区:代币信息(左) + 价格信息(右) 同行展示
class PriceCard extends StatelessWidget {
final Coin coin;
final String tradingStatus;
final VoidCallback? onTapCoin;
const PriceCard({
super.key,
required this.coin,
this.tradingStatus = 'trading',
this.onTapCoin,
});
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isUp = coin.isUp;
final changeColor = isUp ? colorScheme.tertiary : colorScheme.error;
final isTrading = tradingStatus == 'trading';
final isLunch = tradingStatus == 'lunch_break';
final statusLabel = isTrading ? '交易中' : (isLunch ? '午休中' : '已收盘');
final statusColor = isTrading ? colorScheme.tertiary : (isLunch ? Colors.orange : colorScheme.onSurfaceVariant);
final showPrice = true;
return Padding(
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// 左侧:代币信息
GestureDetector(
onTap: onTapCoin,
behavior: HitTestBehavior.opaque,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CoinIcon(symbol: coin.code, size: 28),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
coin.code,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: colorScheme.onSurface),
),
Text(
' /USDT',
style: TextStyle(fontSize: 12, color: colorScheme.onSurfaceVariant),
),
const SizedBox(width: 2),
Icon(LucideIcons.chevronDown, size: 12, color: colorScheme.onSurfaceVariant),
],
),
// 交易状态
Text(
statusLabel,
style: TextStyle(fontSize: 11, color: statusColor, fontWeight: FontWeight.w500),
),
],
),
],
),
),
const Spacer(),
// 右侧:价格 + 涨跌幅
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
showPrice ? coin.formattedPrice : '--',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
color: showPrice ? colorScheme.onSurface : colorScheme.onSurfaceVariant,
),
),
if (showPrice) ...[
const SizedBox(width: 6),
Text(
coin.formattedChange,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: changeColor,
),
),
],
],
),
const SizedBox(height: 4),
// 24h 统计 — 小字一行
Text(
'${_fmt(coin.high24h)}${_fmt(coin.low24h)}${_fmtVol(coin.volume24h)}',
style: TextStyle(fontSize: 10, color: colorScheme.onSurfaceVariant),
),
],
),
],
),
);
}
String _fmt(double? v) {
if (v == null) return '--';
if (v >= 1000) return v.toStringAsFixed(2);
if (v >= 1) return v.toStringAsFixed(4);
return v.toStringAsFixed(6);
}
String _fmtVol(double? v) {
if (v == null) return '--';
if (v >= 1000000) return '${(v / 1000000).toStringAsFixed(2)}M';
if (v >= 1000) return '${(v / 1000).toStringAsFixed(2)}K';
return v.toStringAsFixed(2);
}
}