refactor(theme): 迁移主题感知颜色至 ThemeExtension
- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等) - 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量 - 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂 - 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用 - 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式 - 保持向后兼容性,所有现有功能不变
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user