refactor(theme): 迁移主题感知颜色至 ThemeExtension

- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等)
- 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量
- 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂
- 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用
- 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式
- 保持向后兼容性,所有现有功能不变
This commit is contained in:
2026-04-06 01:58:08 +08:00
parent 396668aa43
commit 7ed2435a4c
36 changed files with 658 additions and 810 deletions

View File

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../data/services/asset_service.dart';
/// 盈亏分析页面 - 月度盈亏日历
@@ -26,26 +26,6 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
WidgetsBinding.instance.addPostFrameCallback((_) => _loadProfit());
}
// ============================================
// 主题感知颜色
// ============================================
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
Color get _upColor => AppColorScheme.getUpColor(_isDark);
Color get _downColor => AppColorScheme.getDownColor(_isDark);
Color get _scaffoldBg =>
_isDark ? AppColorScheme.darkBackground : AppColorScheme.lightBackground;
Color get _cardBg => _isDark
? AppColorScheme.darkSurfaceContainer
: AppColorScheme.lightSurfaceLowest;
Color get _cardBorder => _isDark
? AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15)
: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.5);
// ============================================
// 数据加载
// ============================================
@@ -111,16 +91,15 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final now = DateTime.now();
final isCurrentMonth =
_currentMonth.year == now.year && _currentMonth.month == now.month;
return Scaffold(
backgroundColor: _scaffoldBg,
backgroundColor: context.colors.surface,
appBar: AppBar(
title: const Text('盈亏分析'),
backgroundColor: _scaffoldBg,
backgroundColor: context.colors.surface,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true,
@@ -130,31 +109,30 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
child: Container(
padding: EdgeInsets.all(AppSpacing.lg),
decoration: BoxDecoration(
color: _cardBg,
color: context.appColors.surfaceCard,
borderRadius: BorderRadius.circular(AppRadius.xl),
border: Border.all(color: _cardBorder),
border: Border.all(color: context.appColors.ghostBorder),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 月度盈亏摘要
_buildSummarySection(colorScheme),
_buildSummarySection(),
SizedBox(height: AppSpacing.md),
// 月份导航
_buildMonthNavigation(colorScheme, isCurrentMonth),
_buildMonthNavigation(isCurrentMonth),
SizedBox(height: AppSpacing.sm),
// 星期标题
_buildWeekdayHeaders(colorScheme),
_buildWeekdayHeaders(),
SizedBox(height: AppSpacing.xs),
// 日历网格
if (_isLoading)
_buildLoadingIndicator(colorScheme)
_buildLoadingIndicator()
else
..._buildCalendarGrid(
colorScheme,
now,
isCurrentMonth,
),
@@ -166,16 +144,18 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
}
/// 月度盈亏摘要
Widget _buildSummarySection(ColorScheme colorScheme) {
Widget _buildSummarySection() {
final upColor = context.appColors.up;
final downColor = context.appColors.down;
final isProfit = _monthProfit >= 0;
final color = _isLoading ? colorScheme.onSurfaceVariant : (isProfit ? _upColor : _downColor);
final color = _isLoading ? context.colors.onSurfaceVariant : (isProfit ? upColor : downColor);
return Column(
children: [
Text(
'月度盈亏',
style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant,
color: context.colors.onSurfaceVariant,
),
),
SizedBox(height: AppSpacing.xs),
@@ -193,7 +173,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
}
/// 月份导航行
Widget _buildMonthNavigation(ColorScheme colorScheme, bool isCurrentMonth) {
Widget _buildMonthNavigation(bool isCurrentMonth) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -203,13 +183,13 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
child: Container(
padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration(
color: colorScheme.surfaceContainerHigh,
color: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm),
),
child: Icon(
LucideIcons.chevronLeft,
size: 16,
color: colorScheme.onSurfaceVariant,
color: context.colors.onSurfaceVariant,
),
),
),
@@ -227,16 +207,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration(
color: isCurrentMonth
? colorScheme.surfaceContainerHigh.withValues(alpha: 0.5)
: colorScheme.surfaceContainerHigh,
? context.colors.surfaceContainerHigh.withValues(alpha: 0.5)
: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm),
),
child: Icon(
LucideIcons.chevronRight,
size: 16,
color: isCurrentMonth
? colorScheme.onSurfaceVariant.withValues(alpha: 0.4)
: colorScheme.onSurfaceVariant,
? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
: context.colors.onSurfaceVariant,
),
),
),
@@ -245,7 +225,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
}
/// 星期标题行
Widget _buildWeekdayHeaders(ColorScheme colorScheme) {
Widget _buildWeekdayHeaders() {
return Row(
children: ['', '', '', '', '', '', ''].map((d) {
return Expanded(
@@ -254,7 +234,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
d,
style: AppTextStyles.bodySmall(context).copyWith(
fontWeight: FontWeight.w500,
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.6),
color: context.colors.onSurfaceVariant.withValues(alpha: 0.6),
),
),
),
@@ -264,7 +244,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
}
/// 加载指示器
Widget _buildLoadingIndicator(ColorScheme colorScheme) {
Widget _buildLoadingIndicator() {
return Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl),
child: Center(
@@ -273,7 +253,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: colorScheme.primary,
color: context.colors.primary,
),
),
),
@@ -282,10 +262,11 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
/// 日历网格
List<Widget> _buildCalendarGrid(
ColorScheme colorScheme,
DateTime now,
bool isCurrentMonth,
) {
final upColor = context.appColors.up;
final downColor = context.appColors.down;
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
final daysInMonth =
DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
@@ -313,16 +294,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
margin: EdgeInsets.all(1),
decoration: BoxDecoration(
color: isToday
? colorScheme.primary.withValues(alpha: 0.12)
? context.colors.primary.withValues(alpha: 0.12)
: hasProfit
? (profit! > 0
? _upColor.withValues(alpha: 0.08)
: _downColor.withValues(alpha: 0.08))
? upColor.withValues(alpha: 0.08)
: downColor.withValues(alpha: 0.08))
: Colors.transparent,
borderRadius: BorderRadius.circular(AppRadius.sm),
border: isToday
? Border.all(
color: colorScheme.primary.withValues(alpha: 0.4),
color: context.colors.primary.withValues(alpha: 0.4),
width: 1,
)
: null,
@@ -336,8 +317,8 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
fontSize: 10,
fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
color: isToday
? colorScheme.primary
: colorScheme.onSurface,
? context.colors.primary
: context.colors.onSurface,
),
),
if (hasProfit) ...[
@@ -347,7 +328,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
style: TextStyle(
fontSize: 7,
fontWeight: FontWeight.w600,
color: profit > 0 ? _upColor : _downColor,
color: profit > 0 ? upColor : downColor,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,