|
@@ -11,6 +11,7 @@ import '../../../providers/market_provider.dart';
|
|
|
import '../../widgets/common/app_refresh_indicator.dart';
|
|
import '../../widgets/common/app_refresh_indicator.dart';
|
|
|
import '../../widgets/common/app_shimmer.dart';
|
|
import '../../widgets/common/app_shimmer.dart';
|
|
|
import '../../widgets/common/coin_icon.dart';
|
|
import '../../widgets/common/coin_icon.dart';
|
|
|
|
|
+import '../../widgets/market_list_row_layout.dart';
|
|
|
|
|
|
|
|
/// 行情页列表点击:按当前选中的「永续 / 现货」Tab 跳转对应 K 线详情。
|
|
/// 行情页列表点击:按当前选中的「永续 / 现货」Tab 跳转对应 K 线详情。
|
|
|
void _pushMarketQuoteDetail(
|
|
void _pushMarketQuoteDetail(
|
|
@@ -304,23 +305,20 @@ class _SpotListHeader extends ConsumerWidget {
|
|
|
}) {
|
|
}) {
|
|
|
final active = sortField == field;
|
|
final active = sortField == field;
|
|
|
final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
|
|
final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
|
|
|
- return SizedBox(
|
|
|
|
|
- width: kMarketListChangeBadgeWidth,
|
|
|
|
|
- child: GestureDetector(
|
|
|
|
|
- onTap: () => ref.read(marketProvider.notifier).toggleSpotSort(field),
|
|
|
|
|
- behavior: HitTestBehavior.opaque,
|
|
|
|
|
- child: FittedBox(
|
|
|
|
|
- fit: BoxFit.scaleDown,
|
|
|
|
|
- alignment: Alignment.centerRight,
|
|
|
|
|
- child: Row(
|
|
|
|
|
- mainAxisAlignment: MainAxisAlignment.end,
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(label, style: TextStyle(color: color, fontSize: 12)),
|
|
|
|
|
- const SizedBox(width: 2),
|
|
|
|
|
- _SortIcon(active: active, asc: sortAsc, color: color),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
|
|
+ return GestureDetector(
|
|
|
|
|
+ onTap: () => ref.read(marketProvider.notifier).toggleSpotSort(field),
|
|
|
|
|
+ behavior: HitTestBehavior.opaque,
|
|
|
|
|
+ child: FittedBox(
|
|
|
|
|
+ fit: BoxFit.scaleDown,
|
|
|
|
|
+ alignment: Alignment.center,
|
|
|
|
|
+ child: Row(
|
|
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(label, style: TextStyle(color: color, fontSize: 12)),
|
|
|
|
|
+ const SizedBox(width: 2),
|
|
|
|
|
+ _SortIcon(active: active, asc: sortAsc, color: color),
|
|
|
|
|
+ ],
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
@@ -328,28 +326,22 @@ class _SpotListHeader extends ConsumerWidget {
|
|
|
|
|
|
|
|
return Padding(
|
|
return Padding(
|
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- flex: kMarketListNameClusterFlex,
|
|
|
|
|
- child: sortCell(
|
|
|
|
|
- label: AppLocalizations.of(context)!.nameVolume,
|
|
|
|
|
- field: MarketSortField.volume,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- SizedBox(width: kMarketListNameToPriceGap),
|
|
|
|
|
- sortCell(
|
|
|
|
|
- label: AppLocalizations.of(context)!.latestPriceFull,
|
|
|
|
|
- field: MarketSortField.price,
|
|
|
|
|
- align: MainAxisAlignment.end,
|
|
|
|
|
- ),
|
|
|
|
|
- Spacer(flex: kMarketListPriceTailSpacerFlex),
|
|
|
|
|
- SizedBox(width: kMarketListPriceToBadgeGap),
|
|
|
|
|
- trailingSortCol(
|
|
|
|
|
- label: AppLocalizations.of(context)!.change24hFull,
|
|
|
|
|
- field: MarketSortField.change,
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ child: MarketListHeaderRow(
|
|
|
|
|
+ leading: const SizedBox(width: 30),
|
|
|
|
|
+ leadingGap: 8,
|
|
|
|
|
+ name: sortCell(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.nameVolume,
|
|
|
|
|
+ field: MarketSortField.volume,
|
|
|
|
|
+ ),
|
|
|
|
|
+ price: sortCell(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.latestPriceFull,
|
|
|
|
|
+ field: MarketSortField.price,
|
|
|
|
|
+ align: MainAxisAlignment.end,
|
|
|
|
|
+ ),
|
|
|
|
|
+ change: trailingSortCol(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.change24hFull,
|
|
|
|
|
+ field: MarketSortField.change,
|
|
|
|
|
+ ),
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
@@ -382,106 +374,89 @@ class _SpotTickerRow extends ConsumerWidget {
|
|
|
onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
|
|
onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
|
|
|
child: Padding(
|
|
child: Padding(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- flex: kMarketListNameClusterFlex,
|
|
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- CoinIcon(
|
|
|
|
|
- symbol: ticker.baseAsset, iconUrl: ticker.icon, size: 30),
|
|
|
|
|
- const SizedBox(width: 8),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(
|
|
|
|
|
- formatUsdtPairDisplay(ticker.symbol),
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface,
|
|
|
|
|
- fontSize: 14,
|
|
|
|
|
- fontWeight: FontWeight.w600,
|
|
|
|
|
- ),
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
- ),
|
|
|
|
|
- Text(
|
|
|
|
|
- '${AppLocalizations.of(context)!.spot} · $volumeStr',
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface.withAlpha(120),
|
|
|
|
|
- fontSize: 11,
|
|
|
|
|
- ),
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- SizedBox(width: kMarketListNameToPriceGap),
|
|
|
|
|
- Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(
|
|
|
|
|
- ticker.lastPrice > 0
|
|
|
|
|
- ? (ticker.lastPriceStr != null
|
|
|
|
|
- ? formatRawPrice(ticker.lastPriceStr!)
|
|
|
|
|
- : formatPrice(ticker.lastPrice))
|
|
|
|
|
- : '--',
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface,
|
|
|
|
|
- fontSize: 13,
|
|
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
|
|
- fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.end,
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
|
|
+ child: MarketListDataRow(
|
|
|
|
|
+ leading: CoinIcon(
|
|
|
|
|
+ symbol: ticker.baseAsset,
|
|
|
|
|
+ iconUrl: ticker.icon,
|
|
|
|
|
+ size: 30,
|
|
|
|
|
+ ),
|
|
|
|
|
+ leadingGap: 8,
|
|
|
|
|
+ name: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(
|
|
|
|
|
+ formatUsdtPairDisplay(ticker.symbol),
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
),
|
|
),
|
|
|
- Text(
|
|
|
|
|
- ticker.lastPrice > 0
|
|
|
|
|
- ? formatFiatPrice(ticker.lastPrice,
|
|
|
|
|
- pricePrecision: ticker.pricePrecision)
|
|
|
|
|
- : '--',
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface.withAlpha(120),
|
|
|
|
|
- fontSize: 11,
|
|
|
|
|
- fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.end,
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ ),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ '${AppLocalizations.of(context)!.spot} · $volumeStr',
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface.withAlpha(120),
|
|
|
|
|
+ fontSize: 11,
|
|
|
),
|
|
),
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- Spacer(flex: kMarketListPriceTailSpacerFlex),
|
|
|
|
|
- SizedBox(width: kMarketListPriceToBadgeGap),
|
|
|
|
|
- SizedBox(
|
|
|
|
|
- width: kMarketListChangeBadgeWidth,
|
|
|
|
|
- child: Container(
|
|
|
|
|
- height: 34,
|
|
|
|
|
- decoration: BoxDecoration(
|
|
|
|
|
- color: changeColor,
|
|
|
|
|
- borderRadius: BorderRadius.circular(6),
|
|
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ ),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ price: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(
|
|
|
|
|
+ ticker.lastPrice > 0
|
|
|
|
|
+ ? (ticker.lastPriceStr != null
|
|
|
|
|
+ ? formatRawPrice(ticker.lastPriceStr!)
|
|
|
|
|
+ : formatPrice(ticker.lastPrice))
|
|
|
|
|
+ : '--',
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface,
|
|
|
|
|
+ fontSize: 13,
|
|
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
|
|
+ fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
),
|
|
),
|
|
|
- alignment: Alignment.center,
|
|
|
|
|
- child: Text(
|
|
|
|
|
- ticker.lastPrice > 0 ? changeStr : '--',
|
|
|
|
|
- style: const TextStyle(
|
|
|
|
|
- color: Colors.white,
|
|
|
|
|
- fontSize: 13,
|
|
|
|
|
- fontWeight: FontWeight.w600,
|
|
|
|
|
- fontFeatures: [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.center,
|
|
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ ),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ ticker.lastPrice > 0
|
|
|
|
|
+ ? formatFiatPrice(ticker.lastPrice,
|
|
|
|
|
+ pricePrecision: ticker.pricePrecision)
|
|
|
|
|
+ : '--',
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface.withAlpha(120),
|
|
|
|
|
+ fontSize: 11,
|
|
|
|
|
+ fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
),
|
|
),
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
),
|
|
),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ change: Container(
|
|
|
|
|
+ height: 34,
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ color: changeColor,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(6),
|
|
|
),
|
|
),
|
|
|
- ],
|
|
|
|
|
|
|
+ alignment: Alignment.center,
|
|
|
|
|
+ child: Text(
|
|
|
|
|
+ ticker.lastPrice > 0 ? changeStr : '--',
|
|
|
|
|
+ style: const TextStyle(
|
|
|
|
|
+ color: Colors.white,
|
|
|
|
|
+ fontSize: 13,
|
|
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
|
|
+ fontFeatures: [FontFeature.tabularFigures()],
|
|
|
|
|
+ ),
|
|
|
|
|
+ textAlign: TextAlign.center,
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
@@ -534,27 +509,24 @@ class _ListHeader extends ConsumerWidget {
|
|
|
}) {
|
|
}) {
|
|
|
final active = sortField == field;
|
|
final active = sortField == field;
|
|
|
final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
|
|
final color = active ? cs.onSurface : cs.onSurface.withAlpha(120);
|
|
|
- return SizedBox(
|
|
|
|
|
- width: kMarketListChangeBadgeWidth,
|
|
|
|
|
- child: Semantics(
|
|
|
|
|
- label: semanticsLabel,
|
|
|
|
|
- button: true,
|
|
|
|
|
|
|
+ return Semantics(
|
|
|
|
|
+ label: semanticsLabel,
|
|
|
|
|
+ button: true,
|
|
|
|
|
+ onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
|
|
|
|
|
+ child: GestureDetector(
|
|
|
onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
|
|
onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
|
|
|
- child: GestureDetector(
|
|
|
|
|
- onTap: () => ref.read(marketProvider.notifier).toggleSort(field),
|
|
|
|
|
- behavior: HitTestBehavior.opaque,
|
|
|
|
|
- child: FittedBox(
|
|
|
|
|
- fit: BoxFit.scaleDown,
|
|
|
|
|
- alignment: Alignment.centerRight,
|
|
|
|
|
- child: Row(
|
|
|
|
|
- mainAxisAlignment: MainAxisAlignment.end,
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(label, style: TextStyle(color: color, fontSize: 12)),
|
|
|
|
|
- const SizedBox(width: 2),
|
|
|
|
|
- _SortIcon(active: active, asc: sortAsc, color: color),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
|
|
+ behavior: HitTestBehavior.opaque,
|
|
|
|
|
+ child: FittedBox(
|
|
|
|
|
+ fit: BoxFit.scaleDown,
|
|
|
|
|
+ alignment: Alignment.center,
|
|
|
|
|
+ child: Row(
|
|
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(label, style: TextStyle(color: color, fontSize: 12)),
|
|
|
|
|
+ const SizedBox(width: 2),
|
|
|
|
|
+ _SortIcon(active: active, asc: sortAsc, color: color),
|
|
|
|
|
+ ],
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
@@ -563,28 +535,21 @@ class _ListHeader extends ConsumerWidget {
|
|
|
|
|
|
|
|
return Padding(
|
|
return Padding(
|
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- flex: kMarketListNameClusterFlex,
|
|
|
|
|
- child: buildSortCell(
|
|
|
|
|
- label: AppLocalizations.of(context)!.nameVolume,
|
|
|
|
|
- field: MarketSortField.volume,
|
|
|
|
|
- semanticsLabel: 'market_sort_volume'),
|
|
|
|
|
- ),
|
|
|
|
|
- SizedBox(width: kMarketListNameToPriceGap),
|
|
|
|
|
- buildSortCell(
|
|
|
|
|
- label: AppLocalizations.of(context)!.latestPriceFull,
|
|
|
|
|
- field: MarketSortField.price,
|
|
|
|
|
- align: MainAxisAlignment.end,
|
|
|
|
|
- semanticsLabel: 'market_sort_price'),
|
|
|
|
|
- Spacer(flex: kMarketListPriceTailSpacerFlex),
|
|
|
|
|
- SizedBox(width: kMarketListPriceToBadgeGap),
|
|
|
|
|
- buildTrailingSortCol(
|
|
|
|
|
- label: AppLocalizations.of(context)!.change24hFull,
|
|
|
|
|
- field: MarketSortField.change,
|
|
|
|
|
- semanticsLabel: 'market_sort_change'),
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ child: MarketListHeaderRow(
|
|
|
|
|
+ leading: const SizedBox(width: 40),
|
|
|
|
|
+ name: buildSortCell(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.nameVolume,
|
|
|
|
|
+ field: MarketSortField.volume,
|
|
|
|
|
+ semanticsLabel: 'market_sort_volume'),
|
|
|
|
|
+ price: buildSortCell(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.latestPriceFull,
|
|
|
|
|
+ field: MarketSortField.price,
|
|
|
|
|
+ align: MainAxisAlignment.end,
|
|
|
|
|
+ semanticsLabel: 'market_sort_price'),
|
|
|
|
|
+ change: buildTrailingSortCol(
|
|
|
|
|
+ label: AppLocalizations.of(context)!.change24hFull,
|
|
|
|
|
+ field: MarketSortField.change,
|
|
|
|
|
+ semanticsLabel: 'market_sort_change'),
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
@@ -661,110 +626,85 @@ class _TickerRow extends ConsumerWidget {
|
|
|
onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
|
|
onTap: () => _pushMarketQuoteDetail(context, ref, ticker.symbol),
|
|
|
child: Padding(
|
|
child: Padding(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- // 头像
|
|
|
|
|
- Expanded(
|
|
|
|
|
- flex: kMarketListNameClusterFlex,
|
|
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- CoinIcon(
|
|
|
|
|
- symbol: ticker.baseAsset,
|
|
|
|
|
- iconUrl: ticker.icon,
|
|
|
|
|
- size: 40,
|
|
|
|
|
- borderRadius: 12,
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(width: 10),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(
|
|
|
|
|
- formatUsdtPairDisplay(ticker.symbol),
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface,
|
|
|
|
|
- fontSize: 13,
|
|
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- Text(
|
|
|
|
|
- '${AppLocalizations.of(context)!.perpetual} · $volumeStr',
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface.withAlpha(153),
|
|
|
|
|
- fontSize: 12),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
-
|
|
|
|
|
- SizedBox(width: kMarketListNameToPriceGap),
|
|
|
|
|
- Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(
|
|
|
|
|
- ticker.lastPriceStr != null
|
|
|
|
|
- ? formatRawPrice(ticker.lastPriceStr!)
|
|
|
|
|
- : formatPrice(ticker.lastPrice),
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface,
|
|
|
|
|
- fontSize: 14,
|
|
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
|
|
- fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.end,
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
|
|
+ child: MarketListDataRow(
|
|
|
|
|
+ leading: CoinIcon(
|
|
|
|
|
+ symbol: ticker.baseAsset,
|
|
|
|
|
+ iconUrl: ticker.icon,
|
|
|
|
|
+ size: 40,
|
|
|
|
|
+ borderRadius: 12,
|
|
|
|
|
+ ),
|
|
|
|
|
+ name: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(
|
|
|
|
|
+ formatUsdtPairDisplay(ticker.symbol),
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface,
|
|
|
|
|
+ fontSize: 13,
|
|
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
),
|
|
),
|
|
|
- Text(
|
|
|
|
|
- formatFiatPrice(ticker.lastPrice,
|
|
|
|
|
- pricePrecision: ticker.pricePrecision),
|
|
|
|
|
- style: TextStyle(
|
|
|
|
|
- color: cs.onSurface.withAlpha(153),
|
|
|
|
|
- fontSize: 11,
|
|
|
|
|
- fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.end,
|
|
|
|
|
- maxLines: 1,
|
|
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
|
|
|
|
+ ),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ '${AppLocalizations.of(context)!.perpetual} · $volumeStr',
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface.withAlpha(153),
|
|
|
|
|
+ fontSize: 12,
|
|
|
),
|
|
),
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
-
|
|
|
|
|
- Spacer(flex: kMarketListPriceTailSpacerFlex),
|
|
|
|
|
-
|
|
|
|
|
- const SizedBox(width: kMarketListPriceToBadgeGap),
|
|
|
|
|
-
|
|
|
|
|
- // 涨跌幅 Badge(固定宽度,避免内容宽度抖动)
|
|
|
|
|
- SizedBox(
|
|
|
|
|
- width: kMarketListChangeBadgeWidth,
|
|
|
|
|
- child: Container(
|
|
|
|
|
- height: 34,
|
|
|
|
|
- decoration: BoxDecoration(
|
|
|
|
|
- color: changeColor,
|
|
|
|
|
- borderRadius: BorderRadius.circular(6),
|
|
|
|
|
|
|
+ ),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ price: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Text(
|
|
|
|
|
+ ticker.lastPriceStr != null
|
|
|
|
|
+ ? formatRawPrice(ticker.lastPriceStr!)
|
|
|
|
|
+ : formatPrice(ticker.lastPrice),
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
|
|
+ fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
),
|
|
),
|
|
|
- alignment: Alignment.center,
|
|
|
|
|
- child: Text(
|
|
|
|
|
- changeStr,
|
|
|
|
|
- style: const TextStyle(
|
|
|
|
|
- color: Colors.white,
|
|
|
|
|
- fontSize: 13,
|
|
|
|
|
- fontWeight: FontWeight.w600,
|
|
|
|
|
- fontFeatures: [FontFeature.tabularFigures()],
|
|
|
|
|
- ),
|
|
|
|
|
- textAlign: TextAlign.center,
|
|
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ ),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ formatFiatPrice(ticker.lastPrice,
|
|
|
|
|
+ pricePrecision: ticker.pricePrecision),
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ color: cs.onSurface.withAlpha(153),
|
|
|
|
|
+ fontSize: 11,
|
|
|
|
|
+ fontFeatures: const [FontFeature.tabularFigures()],
|
|
|
),
|
|
),
|
|
|
|
|
+ maxLines: 1,
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
),
|
|
),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ change: Container(
|
|
|
|
|
+ height: 34,
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ color: changeColor,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(6),
|
|
|
),
|
|
),
|
|
|
- ],
|
|
|
|
|
|
|
+ alignment: Alignment.center,
|
|
|
|
|
+ child: Text(
|
|
|
|
|
+ changeStr,
|
|
|
|
|
+ style: const TextStyle(
|
|
|
|
|
+ color: Colors.white,
|
|
|
|
|
+ fontSize: 13,
|
|
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
|
|
+ fontFeatures: [FontFeature.tabularFigures()],
|
|
|
|
|
+ ),
|
|
|
|
|
+ textAlign: TextAlign.center,
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
@@ -784,40 +724,25 @@ class _MarketShimmer extends StatelessWidget {
|
|
|
itemCount: 10,
|
|
itemCount: 10,
|
|
|
itemBuilder: (_, __) => Padding(
|
|
itemBuilder: (_, __) => Padding(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- flex: kMarketListNameClusterFlex,
|
|
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- shimmerCircle(36),
|
|
|
|
|
- const SizedBox(width: 10),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
- children: [
|
|
|
|
|
- shimmerBox(70, 14),
|
|
|
|
|
- const SizedBox(height: 6),
|
|
|
|
|
- shimmerBox(50, 11),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- SizedBox(width: kMarketListNameToPriceGap),
|
|
|
|
|
- Column(
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
- children: [
|
|
|
|
|
- shimmerBox(80, 14),
|
|
|
|
|
- const SizedBox(height: 6),
|
|
|
|
|
- shimmerBox(50, 11),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- Spacer(flex: kMarketListPriceTailSpacerFlex),
|
|
|
|
|
- const SizedBox(width: kMarketListPriceToBadgeGap),
|
|
|
|
|
- shimmerBox(kMarketListChangeBadgeWidth, 30, radius: 6),
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ child: MarketListDataRow(
|
|
|
|
|
+ leading: shimmerCircle(40),
|
|
|
|
|
+ name: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ shimmerBox(70, 14),
|
|
|
|
|
+ const SizedBox(height: 6),
|
|
|
|
|
+ shimmerBox(50, 11),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ price: Column(
|
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ shimmerBox(80, 14),
|
|
|
|
|
+ const SizedBox(height: 6),
|
|
|
|
|
+ shimmerBox(50, 11),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ change: shimmerBox(kMarketListChangeBadgeWidth, 30, radius: 6),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|