fix(theme): 修复亮色模式绿色对比度不足问题

- 添加主题感知颜色函数: getUpColor/getUpBackgroundColor
- app_color_scheme: 新增 getBuyGradient/getEmeraldGradient
- asset_card: emeraldGradient 支持主题切换
- neon_glow: 按钮颜色主题感知
- home_page: 涨跌颜色动态适配
- asset_page: 资产涨跌颜色适配
- trade_page: 交易涨跌颜色适配
- mine_page: 我的页面颜色适配

修复: 亮色模式下绿色 (#00a878) 与浅色背景对比度不足
效果: 亮色模式使用深绿色,深色模式使用亮绿色
This commit is contained in:
2026-03-24 08:58:18 +08:00
parent b4eeb61aa1
commit 7f416c7594
5 changed files with 74 additions and 19 deletions

View File

@@ -153,7 +153,7 @@ class AppColorScheme {
// 语义色 - 明暗通用
// ============================================
/// 涨/买入/成功
/// 涨/买入/成功 (深色主题色,亮色模式下请使用 getUpColor)
static const Color up = darkTertiary;
static const Color success = darkTertiary;
@@ -170,6 +170,42 @@ class AppColorScheme {
/// 信息
static const Color info = Color(0xFF2196F3);
// ============================================
// 主题感知辅助函数 - 根据明暗模式选择正确的颜色
// ============================================
/// 获取涨跌颜色(主题感知)
///
/// 在深色模式下使用亮绿色 (#afffd1),在亮色模式下使用深绿色 (#00a878) 以确保对比度
static Color getUpColor(bool isDark) => isDark ? darkTertiary : lightTertiary;
/// 获取涨跌背景色(主题感知)
///
/// 带透明度的背景色,用于标签、徽章等
static Color getUpBackgroundColor(bool isDark, {double opacity = 0.15}) {
return isDark
? darkTertiary.withValues(alpha: opacity)
: lightTertiary.withValues(alpha: opacity);
}
/// 获取买入按钮渐变(主题感知)
static LinearGradient getBuyGradient(bool isDark) => LinearGradient(
colors: isDark
? [darkTertiary, darkTertiaryContainer]
: [lightTertiary, lightTertiaryContainer],
begin: const Alignment(-0.7, -0.7),
end: const Alignment(0.7, 0.7),
);
/// 获取翡翠渐变(主题感知)- 用于盈利展示
static LinearGradient getEmeraldGradient(bool isDark) => LinearGradient(
colors: isDark
? [darkTertiary, const Color(0xFF7de8b8)]
: [lightTertiary, const Color(0xFF00c987)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
// ============================================
// 渐变预设
// ============================================
@@ -434,12 +470,25 @@ ShadThemeData createLightShadTheme() {
);
}
/// 获取涨跌颜色(明暗通用)
/// 获取涨跌颜色(明暗通用)- 已废弃,请使用带主题感知的版本
@Deprecated('Use AppColorScheme.getUpColor(isDark) instead')
Color getChangeColor(bool isUp) => isUp ? AppColorScheme.up : AppColorScheme.down;
/// 获取涨跌背景色(带透明度)
/// 获取涨跌背景色(带透明度)- 已废弃,请使用带主题感知的版本
@Deprecated('Use AppColorScheme.getUpBackgroundColor(isDark, opacity: opacity) instead')
Color getChangeBackgroundColor(bool isUp, {double opacity = 0.15}) {
return isUp
? AppColorScheme.up.withValues(alpha: opacity)
: AppColorScheme.down.withValues(alpha: opacity);
}
/// 获取涨跌颜色(主题感知)
Color getChangeColorThemeAware(bool isUp, bool isDark) =>
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down;
/// 获取涨跌背景色(主题感知)
Color getChangeBackgroundColorThemeAware(bool isUp, bool isDark, {double opacity = 0.15}) {
return isUp
? AppColorScheme.getUpBackgroundColor(isDark, opacity: opacity)
: AppColorScheme.down.withValues(alpha: opacity);
}

View File

@@ -30,9 +30,11 @@ class AssetCard extends StatelessWidget {
end: Alignment.bottomRight,
);
/// 翡翠渐变 - 用于盈利展示
static const emeraldGradient = LinearGradient(
colors: [AppColorScheme.darkTertiary, Color(0xFF7de8b8)],
/// 翡翠渐变 - 用于盈利展示(主题感知)
static LinearGradient getEmeraldGradient(bool isDark) => LinearGradient(
colors: isDark
? [AppColorScheme.darkTertiary, const Color(0xFF7de8b8)]
: [AppColorScheme.lightTertiary, const Color(0xFF00c987)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);

View File

@@ -214,7 +214,7 @@ class _NeonButtonState extends State<NeonButton>
case NeonButtonType.secondary:
return colorScheme.secondary;
case NeonButtonType.tertiary:
return AppColorScheme.up;
return AppColorScheme.getUpColor(isDark);
case NeonButtonType.error:
return AppColorScheme.down;
case NeonButtonType.outline:
@@ -250,7 +250,7 @@ class _NeonButtonState extends State<NeonButton>
case NeonButtonType.secondary:
return colorScheme.secondary.withOpacity(isDark ? 0.15 : 0.08);
case NeonButtonType.tertiary:
return AppColorScheme.up.withOpacity(isDark ? 0.2 : 0.1);
return AppColorScheme.getUpBackgroundColor(isDark, opacity: isDark ? 0.2 : 0.1);
case NeonButtonType.error:
return AppColorScheme.down.withOpacity(0.3);
case NeonButtonType.outline:
@@ -278,7 +278,7 @@ class _NeonButtonState extends State<NeonButton>
end: const Alignment(0.7, 0.7),
);
case NeonButtonType.tertiary:
return AppColorScheme.buyGradient;
return AppColorScheme.getBuyGradient(isDark);
case NeonButtonType.error:
return AppColorScheme.sellGradient;
default:

View File

@@ -406,6 +406,7 @@ class _HoldingItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.sm),
@@ -464,7 +465,7 @@ class _HoldingItem extends StatelessWidget {
Text(
holding.formattedProfitRate,
style: TextStyle(
color: holding.isProfit ? AppColorScheme.up : AppColorScheme.down,
color: holding.isProfit ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down,
fontSize: 12,
fontWeight: FontWeight.w600,
),
@@ -598,6 +599,7 @@ void _showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
final walletAddress = data['walletAddress'] as String? ?? '';
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showShadDialog(
context: context,
@@ -614,7 +616,7 @@ void _showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
children: [
NeonIcon(
icon: Icons.check_circle,
color: AppColorScheme.up,
color: AppColorScheme.getUpColor(isDark),
size: 24,
),
SizedBox(width: AppSpacing.sm),

View File

@@ -328,7 +328,7 @@ class _GlassBalanceCard extends StatelessWidget {
Container(
padding: EdgeInsets.symmetric(horizontal: AppSpacing.sm, vertical: AppSpacing.xs),
decoration: BoxDecoration(
color: AppColorScheme.up.withOpacity(0.1),
color: AppColorScheme.getUpBackgroundColor(isDark, opacity: 0.1),
borderRadius: BorderRadius.circular(AppRadius.md),
),
child: Row(
@@ -336,14 +336,14 @@ class _GlassBalanceCard extends StatelessWidget {
children: [
Icon(
LucideIcons.trendingUp,
color: AppColorScheme.up,
color: AppColorScheme.getUpColor(isDark),
size: 16,
),
SizedBox(width: AppSpacing.xs),
Text(
'+0.00%',
style: TextStyle(
color: AppColorScheme.up,
color: AppColorScheme.getUpColor(isDark),
fontWeight: FontWeight.bold,
fontSize: 14,
),
@@ -382,6 +382,7 @@ class _QuickActionsGrid extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -401,7 +402,7 @@ class _QuickActionsGrid extends StatelessWidget {
_QuickActionBtn(
icon: LucideIcons.arrowRightLeft,
label: '划转',
color: AppColorScheme.up,
color: AppColorScheme.getUpColor(isDark),
onTap: onTransfer,
),
_QuickActionBtn(
@@ -627,14 +628,14 @@ class _EmptyHoldings extends StatelessWidget {
height: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColorScheme.up.withOpacity(0.2),
color: AppColorScheme.getUpBackgroundColor(isDark, opacity: 0.2),
border: Border.all(
color: AppColorScheme.up.withOpacity(0.3),
color: AppColorScheme.getUpBackgroundColor(isDark, opacity: 0.3),
),
),
child: Icon(
LucideIcons.coins,
color: AppColorScheme.up,
color: AppColorScheme.getUpColor(isDark),
size: 20,
),
),
@@ -746,6 +747,7 @@ class _HoldingItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.sm + AppSpacing.xs),
@@ -802,7 +804,7 @@ class _HoldingItem extends StatelessWidget {
Text(
holding.formattedProfitRate,
style: TextStyle(
color: holding.isProfit ? AppColorScheme.up : AppColorScheme.down,
color: holding.isProfit ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down,
fontSize: 12,
fontWeight: FontWeight.w500,
),