refactor(theme): 迁移主题感知颜色至 ThemeExtension
- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等) - 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量 - 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂 - 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用 - 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式 - 保持向后兼容性,所有现有功能不变
This commit is contained in:
@@ -7,13 +7,13 @@ import 'package:provider/provider.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 '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../data/models/account_models.dart';
|
||||
import '../../../data/services/asset_service.dart';
|
||||
import '../../../data/services/bonus_service.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
import '../../components/neon_glow.dart';
|
||||
import '../main/main_page.dart';
|
||||
@@ -85,15 +85,14 @@ class _HomePageState extends State<HomePage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
backgroundColor: context.colors.background,
|
||||
body: Consumer<AssetProvider>(
|
||||
builder: (context, provider, _) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => provider.refreshAll(force: true),
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(
|
||||
@@ -149,7 +148,6 @@ class _HomePageState extends State<HomePage>
|
||||
void _showDeposit() {
|
||||
final amountController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -184,10 +182,10 @@ class _HomePageState extends State<HomePage>
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
child: Icon(LucideIcons.wallet, color: colorScheme.secondary),
|
||||
child: Icon(LucideIcons.wallet, color: context.colors.secondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -261,7 +259,6 @@ class _HomePageState extends State<HomePage>
|
||||
final amount = data['amount']?.toString() ?? '0.00';
|
||||
final walletAddress = data['walletAddress'] as String? ?? '';
|
||||
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -305,9 +302,9 @@ class _HomePageState extends State<HomePage>
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.warning.withOpacity(0.1),
|
||||
color: AppColorScheme.warning.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
border: Border.all(color: AppColorScheme.warning.withOpacity(0.2)),
|
||||
border: Border.all(color: AppColorScheme.warning.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -371,7 +368,6 @@ class _HomePageState extends State<HomePage>
|
||||
}
|
||||
|
||||
void _showResultDialog(String title, String? message) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
@@ -525,10 +521,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final upColor = AppColorScheme.getUpColor(isDark);
|
||||
final downColor = AppColorScheme.getDownColor(isDark);
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final isProfit = _totalProfit >= 0;
|
||||
final todayProfit = _todayProfit;
|
||||
final isTodayProfit = (todayProfit ?? 0) >= 0;
|
||||
@@ -558,19 +552,19 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
vertical: AppSpacing.xs + 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
color: context.colors.primary.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
border: Border.all(color: context.colors.primary.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, size: 14, color: colorScheme.primary),
|
||||
Icon(Icons.add, size: 14, color: context.colors.primary),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'充值',
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -620,11 +614,11 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary.withOpacity(0.1)
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
? context.colors.primary.withValues(alpha: 0.1)
|
||||
: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: _calendarExpanded
|
||||
? Border.all(color: colorScheme.primary.withOpacity(0.2))
|
||||
? Border.all(color: context.colors.primary.withValues(alpha: 0.2))
|
||||
: null,
|
||||
),
|
||||
child: Row(
|
||||
@@ -634,8 +628,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
LucideIcons.chartBar,
|
||||
size: 13,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
@@ -643,8 +637,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
fontWeight: _calendarExpanded ? FontWeight.w600 : FontWeight.w500,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 2),
|
||||
@@ -655,8 +649,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
LucideIcons.chevronDown,
|
||||
size: 13,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -669,9 +663,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
// 可折叠的盈利日历
|
||||
AnimatedCrossFade(
|
||||
firstChild: const SizedBox.shrink(),
|
||||
secondChild: _buildCalendarSection(
|
||||
context, colorScheme, isDark, upColor, downColor,
|
||||
),
|
||||
secondChild: _buildCalendarSection(context),
|
||||
crossFadeState: _calendarExpanded
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
@@ -683,18 +675,14 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendarSection(
|
||||
BuildContext context,
|
||||
ColorScheme colorScheme,
|
||||
bool isDark,
|
||||
Color upColor,
|
||||
Color downColor,
|
||||
) {
|
||||
Widget _buildCalendarSection(BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final isCurrentMonth = _currentMonth.year == now.year && _currentMonth.month == now.month;
|
||||
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
|
||||
final daysInMonth = DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
|
||||
final startWeekday = firstDayOfMonth.weekday;
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -702,7 +690,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
// 分隔线
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.md),
|
||||
child: Divider(color: colorScheme.outlineVariant.withOpacity(0.15), height: 1),
|
||||
child: Divider(color: context.appColors.ghostBorder, height: 1),
|
||||
),
|
||||
|
||||
// 月份导航行
|
||||
@@ -714,10 +702,10 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
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),
|
||||
child: Icon(LucideIcons.chevronLeft, size: 16, color: context.colors.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
@@ -745,16 +733,16 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
padding: EdgeInsets.all(AppSpacing.xs + 1),
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentMonth
|
||||
? colorScheme.surfaceContainerHigh.withOpacity(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.withOpacity(0.4)
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -771,7 +759,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
d,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
color: context.colors.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -789,14 +777,13 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
..._buildCalendarGrid(
|
||||
startWeekday, daysInMonth, now, isCurrentMonth,
|
||||
upColor, downColor, colorScheme,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -807,10 +794,9 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
int daysInMonth,
|
||||
DateTime now,
|
||||
bool isCurrentMonth,
|
||||
Color upColor,
|
||||
Color downColor,
|
||||
ColorScheme colorScheme,
|
||||
) {
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final List<Widget> rows = [];
|
||||
List<Widget> cells = [];
|
||||
|
||||
@@ -831,15 +817,15 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
margin: EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: isToday
|
||||
? colorScheme.primary.withOpacity(0.12)
|
||||
? context.colors.primary.withValues(alpha: 0.12)
|
||||
: hasProfit
|
||||
? (profit! > 0
|
||||
? upColor.withOpacity(0.08)
|
||||
: downColor.withOpacity(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.withOpacity(0.4), width: 1)
|
||||
? Border.all(color: context.colors.primary.withValues(alpha: 0.4), width: 1)
|
||||
: null,
|
||||
),
|
||||
child: Column(
|
||||
@@ -851,8 +837,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
fontSize: 10,
|
||||
fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
|
||||
color: isToday
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurface,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurface,
|
||||
),
|
||||
),
|
||||
if (hasProfit) ...[
|
||||
@@ -906,9 +892,6 @@ class _WelfareCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
@@ -917,14 +900,14 @@ class _WelfareCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
colorScheme.primary.withOpacity(0.15),
|
||||
colorScheme.secondary.withOpacity(0.1),
|
||||
context.colors.primary.withValues(alpha: 0.15),
|
||||
context.colors.secondary.withValues(alpha: 0.1),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
border: Border.all(color: context.colors.primary.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -933,12 +916,12 @@ class _WelfareCard extends StatelessWidget {
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.15),
|
||||
color: context.colors.primary.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.gift,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -971,9 +954,7 @@ class _WelfareCard extends StatelessWidget {
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isDark
|
||||
? AppColorScheme.darkCtaGradient
|
||||
: AppColorScheme.lightCtaGradient,
|
||||
gradient: context.appColors.ctaGradient,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1000,7 +981,7 @@ class _WelfareCard extends StatelessWidget {
|
||||
'查看',
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark ? colorScheme.background : AppColorScheme.darkOnPrimary,
|
||||
color: context.colors.onPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1021,8 +1002,6 @@ class _HoldingsSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
@@ -1037,7 +1016,7 @@ class _HoldingsSection extends StatelessWidget {
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: colorScheme.primary,
|
||||
foregroundColor: context.colors.primary,
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1048,7 +1027,7 @@ class _HoldingsSection extends StatelessWidget {
|
||||
)),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Icon(LucideIcons.chevronRight,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -1067,19 +1046,17 @@ class _EmptyHoldings extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl, horizontal: AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerLow.withOpacity(0.5),
|
||||
color: context.colors.surfaceContainerLow.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.1)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(LucideIcons.wallet, size: 48, color: colorScheme.onSurfaceVariant),
|
||||
Icon(LucideIcons.wallet, size: 48, color: context.colors.onSurfaceVariant),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
'暂无持仓',
|
||||
@@ -1106,15 +1083,14 @@ class _HoldingsList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final displayHoldings =
|
||||
holdings.length > 5 ? holdings.sublist(0, 5) : holdings;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surface.withOpacity(0.5),
|
||||
color: context.colors.surface.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.1)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
@@ -1122,7 +1098,7 @@ class _HoldingsList extends StatelessWidget {
|
||||
padding: EdgeInsets.all(AppSpacing.md),
|
||||
itemCount: displayHoldings.length,
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.1),
|
||||
color: context.colors.outlineVariant.withValues(alpha: 0.1),
|
||||
height: 1,
|
||||
),
|
||||
itemBuilder: (context, index) =>
|
||||
@@ -1140,9 +1116,6 @@ 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),
|
||||
child: Row(
|
||||
@@ -1152,11 +1125,11 @@ class _HoldingItem extends StatelessWidget {
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: colorScheme.primary.withOpacity(0.1),
|
||||
backgroundColor: context.colors.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
holding.coinCode.substring(0, 1),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@@ -1185,8 +1158,8 @@ class _HoldingItem extends StatelessWidget {
|
||||
Text(holding.formattedProfitRate,
|
||||
style: AppTextStyles.numberSmall(context).copyWith(
|
||||
color: holding.isProfit
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark),
|
||||
? context.appColors.up
|
||||
: context.appColors.down,
|
||||
)),
|
||||
],
|
||||
),
|
||||
@@ -1206,8 +1179,6 @@ class _InfoRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -1232,14 +1203,12 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.3)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1262,11 +1231,11 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
color: context.colors.primary.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(LucideIcons.copy,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1298,22 +1267,21 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final hasValue = value != null;
|
||||
final isProfit = (value ?? 0) >= 0;
|
||||
final color = hasValue ? (isProfit ? upColor : downColor) : colorScheme.onSurfaceVariant;
|
||||
final color = hasValue ? (isProfit ? upColor : downColor) : context.colors.onSurfaceVariant;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm + 2),
|
||||
decoration: BoxDecoration(
|
||||
color: hasValue
|
||||
? (isProfit ? upColor : downColor).withOpacity(0.06)
|
||||
: colorScheme.surfaceContainerHigh.withOpacity(0.5),
|
||||
? (isProfit ? upColor : downColor).withValues(alpha: 0.06)
|
||||
: context.colors.surfaceContainerHigh.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: hasValue
|
||||
? (isProfit ? upColor : downColor).withOpacity(0.12)
|
||||
: colorScheme.outlineVariant.withOpacity(0.1),
|
||||
? (isProfit ? upColor : downColor).withValues(alpha: 0.12)
|
||||
: context.colors.outlineVariant.withValues(alpha: 0.1),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
@@ -1326,14 +1294,14 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
? (isProfit ? LucideIcons.trendingUp : LucideIcons.trendingDown)
|
||||
: LucideIcons.minus,
|
||||
size: 11,
|
||||
color: color.withOpacity(0.7),
|
||||
color: color.withValues(alpha: 0.7),
|
||||
),
|
||||
SizedBox(width: 3),
|
||||
Text(
|
||||
label,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: color.withOpacity(0.8),
|
||||
color: color.withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.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';
|
||||
|
||||
/// 首页热门币种区块
|
||||
class HotCoinsSection extends StatelessWidget {
|
||||
@@ -10,9 +10,6 @@ class HotCoinsSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
// Title row
|
||||
@@ -36,9 +33,9 @@ class HotCoinsSection extends StatelessWidget {
|
||||
// Card
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainer,
|
||||
color: context.colors.surfaceContainer,
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant,
|
||||
color: context.colors.outlineVariant,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
@@ -52,13 +49,11 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '68,432.50',
|
||||
change: '+2.35%',
|
||||
isUp: true,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
_CoinRow(
|
||||
symbol: 'ETH',
|
||||
@@ -67,13 +62,11 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '3,856.20',
|
||||
change: '+1.82%',
|
||||
isUp: true,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
_CoinRow(
|
||||
symbol: 'SOL',
|
||||
@@ -82,8 +75,6 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '178.65',
|
||||
change: '-0.94%',
|
||||
isUp: false,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -101,8 +92,6 @@ class _CoinRow extends StatelessWidget {
|
||||
required this.price,
|
||||
required this.change,
|
||||
required this.isUp,
|
||||
required this.colorScheme,
|
||||
required this.isDark,
|
||||
});
|
||||
|
||||
final String symbol;
|
||||
@@ -111,14 +100,12 @@ class _CoinRow extends StatelessWidget {
|
||||
final String price;
|
||||
final String change;
|
||||
final bool isUp;
|
||||
final ColorScheme colorScheme;
|
||||
final bool isDark;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final changeColor = isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md),
|
||||
@@ -130,13 +117,13 @@ class _CoinRow extends StatelessWidget {
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: colorScheme.primary.withValues(alpha: 0.1),
|
||||
backgroundColor: context.colors.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
symbol,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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