refactor(theme): 迁移主题感知颜色至 ThemeExtension
- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等) - 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量 - 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂 - 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用 - 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式 - 保持向后兼容性,所有现有功能不变
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'coin_avatar.dart';
|
||||
|
||||
@@ -25,21 +25,16 @@ class CoinSelector extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _showCoinPicker(context),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -60,14 +55,14 @@ class CoinSelector extends StatelessWidget {
|
||||
Text(
|
||||
selectedCoin?.name ?? '点击选择交易对',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// 下拉箭头
|
||||
Icon(LucideIcons.chevronDown,
|
||||
size: 16, color: colorScheme.onSurfaceVariant),
|
||||
size: 16, color: context.colors.onSurfaceVariant),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -75,9 +70,6 @@ class CoinSelector extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showCoinPicker(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
@@ -85,9 +77,9 @@ class CoinSelector extends StatelessWidget {
|
||||
builder: (ctx) => Container(
|
||||
height: MediaQuery.of(ctx).size.height * 0.65,
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surface
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: ctx.isDark
|
||||
? ctx.colors.surface
|
||||
: ctx.colors.surfaceContainerLowest,
|
||||
borderRadius:
|
||||
BorderRadius.vertical(top: Radius.circular(AppRadius.xxl)),
|
||||
),
|
||||
@@ -99,7 +91,7 @@ class CoinSelector extends StatelessWidget {
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.3),
|
||||
color: ctx.colors.onSurfaceVariant.withValues(alpha: 0.3),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
),
|
||||
@@ -114,12 +106,12 @@ class CoinSelector extends StatelessWidget {
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(ctx).pop(),
|
||||
child: Icon(LucideIcons.x,
|
||||
color: colorScheme.onSurfaceVariant),
|
||||
color: ctx.colors.onSurfaceVariant),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1, color: colorScheme.outlineVariant.withOpacity(0.2)),
|
||||
Divider(height: 1, color: ctx.colors.outlineVariant.withValues(alpha: 0.2)),
|
||||
// 币种列表
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
@@ -137,12 +129,10 @@ class CoinSelector extends StatelessWidget {
|
||||
|
||||
Widget _buildCoinItem(
|
||||
Coin coin, BuildContext context, BuildContext sheetContext) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isSelected = selectedCoin?.code == coin.code;
|
||||
final changeColor = coin.isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
@@ -153,7 +143,7 @@ class CoinSelector extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.lg, vertical: AppSpacing.md),
|
||||
color:
|
||||
isSelected ? colorScheme.primary.withOpacity(0.1) : const Color(0x00000000),
|
||||
isSelected ? context.colors.primary.withValues(alpha: 0.1) : const Color(0x00000000),
|
||||
child: Row(
|
||||
children: [
|
||||
CoinAvatar(icon: coin.displayIcon),
|
||||
@@ -170,7 +160,7 @@ class CoinSelector extends StatelessWidget {
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text('/USDT',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
const Spacer(),
|
||||
Text('\$${coin.formattedPrice}',
|
||||
@@ -180,7 +170,7 @@ class CoinSelector extends StatelessWidget {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: changeColor.withOpacity(0.1),
|
||||
color: changeColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(coin.formattedChange,
|
||||
@@ -192,7 +182,7 @@ class CoinSelector extends StatelessWidget {
|
||||
if (isSelected) ...[
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
Icon(LucideIcons.check,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -200,7 +190,7 @@ class CoinSelector extends StatelessWidget {
|
||||
// 第二行:币种名称
|
||||
Text(coin.name,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
import '../../../components/neon_glow.dart';
|
||||
|
||||
@@ -27,11 +27,9 @@ class ConfirmDialog extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final actionColor = isBuy
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return Dialog(
|
||||
backgroundColor: const Color(0x00000000),
|
||||
@@ -49,14 +47,14 @@ class ConfirmDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
_dialogRow(context, '交易对', '$coinCode/USDT', colorScheme),
|
||||
_dialogRow(context, '交易对', '$coinCode/USDT'),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '委托价格', '$price USDT', colorScheme),
|
||||
_dialogRow(context, '委托价格', '$price USDT'),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '交易金额', '$amount USDT', colorScheme,
|
||||
_dialogRow(context, '交易金额', '$amount USDT',
|
||||
valueColor: actionColor),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '交易数量', '$quantity $coinCode', colorScheme),
|
||||
_dialogRow(context, '交易数量', '$quantity $coinCode'),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
Row(
|
||||
children: [
|
||||
@@ -87,7 +85,7 @@ class ConfirmDialog extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _dialogRow(BuildContext context, String label, String value, ColorScheme colorScheme,
|
||||
Widget _dialogRow(BuildContext context, String label, String value,
|
||||
{Color? valueColor}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -95,11 +93,11 @@ class ConfirmDialog extends StatelessWidget {
|
||||
Text(label,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text(value,
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
color: valueColor ?? colorScheme.onSurface,
|
||||
color: valueColor ?? context.colors.onSurface,
|
||||
)),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,38 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 占位卡片组件
|
||||
///
|
||||
/// 当未选择币种时显示的占位提示卡片。
|
||||
class PlaceholderCard extends StatelessWidget {
|
||||
final String message;
|
||||
final ColorScheme colorScheme;
|
||||
const PlaceholderCard({
|
||||
super.key,
|
||||
required this.message,
|
||||
required this.colorScheme,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(message,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
|
||||
/// 价格卡片组件
|
||||
@@ -14,25 +14,21 @@ class PriceCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isUp = coin.isUp;
|
||||
final changeColor =
|
||||
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark);
|
||||
isUp ? context.appColors.up : context.appColors.down;
|
||||
final changeBgColor = isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark)
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
? context.appColors.upBackground
|
||||
: context.appColors.downBackground;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'amount_input.dart';
|
||||
|
||||
@@ -37,17 +38,13 @@ class TradeFormCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isBuy = tradeType == 0;
|
||||
final actionColor = isBuy
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
// 设计稿中 card 背景色
|
||||
final cardBgColor = isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest;
|
||||
final cardBgColor = context.appColors.surfaceCard;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@@ -56,7 +53,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
color: cardBgColor,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
@@ -83,7 +80,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
border: isBuy
|
||||
? null
|
||||
: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15)),
|
||||
color: context.appColors.ghostBorder),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
@@ -91,7 +88,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isBuy
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -113,7 +110,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
border: !isBuy
|
||||
? null
|
||||
: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15)),
|
||||
color: context.appColors.ghostBorder),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
@@ -121,7 +118,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: !isBuy
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -139,7 +136,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
children: [
|
||||
Text('交易金额',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text('USDT',
|
||||
style: AppTextStyles.labelLarge(context)),
|
||||
@@ -163,7 +160,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
? '可用: $availableUsdt USDT'
|
||||
: '可用: $availableCoinQty ${selectedCoin?.code ?? ""}',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -172,13 +169,13 @@ class TradeFormCard extends StatelessWidget {
|
||||
// 设计稿:gap:8,圆角sm,bg-tertiary,高32
|
||||
Row(
|
||||
children: [
|
||||
_buildPctButton(context, '25%', 0.25, colorScheme),
|
||||
_buildPctButton(context, '25%', 0.25),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '50%', 0.5, colorScheme),
|
||||
_buildPctButton(context, '50%', 0.5),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '75%', 0.75, colorScheme),
|
||||
_buildPctButton(context, '75%', 0.75),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '100%', 1.0, colorScheme),
|
||||
_buildPctButton(context, '100%', 1.0),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md + AppSpacing.sm),
|
||||
@@ -189,7 +186,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
children: [
|
||||
Text('交易数量',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text(
|
||||
'$calculatedQuantity ${selectedCoin?.code ?? ''}',
|
||||
@@ -203,20 +200,20 @@ class TradeFormCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// 百分比按钮 - 设计稿:圆角sm,bg-tertiary,高32
|
||||
Widget _buildPctButton(BuildContext context, String label, double pct, ColorScheme colorScheme) {
|
||||
Widget _buildPctButton(BuildContext context, String label, double pct) {
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => onFillPercent(pct),
|
||||
child: Container(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHighest.withOpacity(0.5),
|
||||
color: context.colors.surfaceContainerHighest.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(label,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user