refactor(theme): 迁移主题感知颜色至 ThemeExtension
- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等) - 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量 - 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂 - 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用 - 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式 - 保持向后兼容性,所有现有功能不变
This commit is contained in:
@@ -2,9 +2,9 @@ import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.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 '../../../providers/market_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
@@ -34,10 +34,9 @@ class _MarketPageState extends State<MarketPage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
backgroundColor: context.colors.surface,
|
||||
body: Consumer<MarketProvider>(
|
||||
builder: (context, provider, _) {
|
||||
if (provider.isLoading) {
|
||||
@@ -50,8 +49,8 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => provider.refresh(),
|
||||
color: colorScheme.primary,
|
||||
backgroundColor: colorScheme.surfaceContainerHighest,
|
||||
color: context.colors.primary,
|
||||
backgroundColor: context.colors.surfaceContainerHighest,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(
|
||||
@@ -114,8 +113,6 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
/// 分区标题:全部币种 + 更多
|
||||
Widget _buildSectionHeader() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -126,7 +123,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
Text(
|
||||
'更多 >',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -136,7 +133,6 @@ class _MarketPageState extends State<MarketPage>
|
||||
/// 币种列表
|
||||
Widget _buildCoinList(MarketProvider provider) {
|
||||
final coins = provider.otherCoins;
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
if (coins.isEmpty) {
|
||||
return _EmptyState(
|
||||
@@ -148,10 +144,10 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainer,
|
||||
color: context.colors.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -162,7 +158,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.5 * 0.15),
|
||||
color: context.colors.outlineVariant.withValues(alpha: 0.5 * 0.15),
|
||||
indent: AppSpacing.md,
|
||||
endIndent: AppSpacing.md,
|
||||
),
|
||||
@@ -173,18 +169,17 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
/// 错误状态
|
||||
Widget _buildErrorState(MarketProvider provider) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: AppSpacing.pagePadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(LucideIcons.circleAlert, size: 48, color: colorScheme.error),
|
||||
Icon(LucideIcons.circleAlert, size: 48, color: context.colors.error),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
provider.error ?? '加载失败',
|
||||
style: TextStyle(color: colorScheme.error),
|
||||
style: TextStyle(color: context.colors.error),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -207,14 +202,12 @@ class _FeaturedCard 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.down;
|
||||
isUp ? context.appColors.up : context.appColors.down;
|
||||
final changeBgColor = isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark)
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
? context.appColors.upBackground
|
||||
: context.appColors.downBackground;
|
||||
|
||||
return GlassPanel(
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -255,12 +248,12 @@ class _FeaturedCard extends StatelessWidget {
|
||||
Text(
|
||||
coin.name,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
// 第四行:迷你柱状图
|
||||
Expanded(
|
||||
child: _MiniBarChart(isUp: isUp, isDark: isDark, seed: coin.code.hashCode),
|
||||
child: _MiniBarChart(isUp: isUp, seed: coin.code.hashCode),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -295,16 +288,15 @@ class _FeaturedCard extends StatelessWidget {
|
||||
/// 迷你柱状图(模拟价格走势)
|
||||
class _MiniBarChart extends StatelessWidget {
|
||||
final bool isUp;
|
||||
final bool isDark;
|
||||
final int seed;
|
||||
|
||||
const _MiniBarChart({required this.isUp, required this.isDark, required this.seed});
|
||||
const _MiniBarChart({required this.isUp, required this.seed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final barColor = isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
// 生成随机但确定的高度序列
|
||||
final heights = _generateHeights();
|
||||
@@ -345,14 +337,12 @@ class _CoinRow 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 GestureDetector(
|
||||
onTap: () => _navigateToTrade(context),
|
||||
@@ -428,12 +418,8 @@ class _CoinAvatar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
// 从 .pen 设计中的 accent-light 和 accent-primary
|
||||
final bgColor = colorScheme.primary.withValues(alpha: isDark ? 0.15 : 0.1);
|
||||
final textColor = colorScheme.primary;
|
||||
final bgColor = context.colors.primary.withValues(alpha: context.appColors.glowOpacity);
|
||||
|
||||
return Container(
|
||||
width: 36,
|
||||
@@ -447,7 +433,7 @@ class _CoinAvatar extends StatelessWidget {
|
||||
_getLetter(),
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: textColor,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -477,18 +463,16 @@ class _EmptyState extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, size: 48, color: colorScheme.onSurfaceVariant),
|
||||
Icon(icon, size: 48, color: context.colors.onSurfaceVariant),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
||||
style: TextStyle(color: context.colors.onSurfaceVariant),
|
||||
),
|
||||
if (onRetry != null) ...[
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
Reference in New Issue
Block a user