style: 完成前端专业金融风格优化

- 主题配色: 黑金传奇(暗) + 白金殿堂(亮)
- 底部导航: 去掉毛玻璃,简洁专业
- 交易页面: 明亮模式颜色优化,实心按钮
- 按钮圆角: xxl(24px) → lg(12px)/md(8px)
- 字体系统: Inter(币安同款)
- 整体风格: 专业金融科技
This commit is contained in:
2026-03-30 03:31:42 +08:00
parent f32c48900b
commit 8825fe5b27
7 changed files with 10898 additions and 10903 deletions

View File

@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"e4b8dca3f1b4ede4c30371002441c88c12187e
_flutter.loader.load({ _flutter.loader.load({
serviceWorkerSettings: { serviceWorkerSettings: {
serviceWorkerVersion: "2749146521" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */ serviceWorkerVersion: "2301510877" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
} }
}); });

File diff suppressed because one or more lines are too long

View File

@@ -129,7 +129,7 @@ class AppColorScheme {
static const Color lightTertiaryContainer = Color(0xFFd4f5e9); static const Color lightTertiaryContainer = Color(0xFFd4f5e9);
/// 文本色 /// 文本色
static const Color lightOnSurface = Color(0xFF2c2f31); static const Color lightOnSurface = Color(0xFF1A1A1A);
static const Color lightOnSurfaceVariant = Color(0xFF5a5d60); static const Color lightOnSurfaceVariant = Color(0xFF5a5d60);
static const Color lightOnSurfaceMuted = Color(0xFF8a8d90); static const Color lightOnSurfaceMuted = Color(0xFF8a8d90);
@@ -195,6 +195,22 @@ class AppColorScheme {
: lightTertiary.withValues(alpha: opacity); : lightTertiary.withValues(alpha: opacity);
} }
/// 获取跌/卖出颜色(主题感知)
static Color getDownColor(bool isDark) => isDark ? darkError : lightError;
/// 获取跌/卖出背景色(主题感知)
static Color getDownBackgroundColor(bool isDark, {double opacity = 0.15}) {
return isDark
? darkError.withValues(alpha: opacity)
: lightError.withValues(alpha: opacity);
}
/// 交易按钮买入色 - 深绿色填充,确保白色文字可读
static const Color buyButtonFill = Color(0xFF059669);
/// 交易按钮卖出色 - 深红色填充,确保白色文字可读
static const Color sellButtonFill = Color(0xFFDC2626);
/// 获取买入按钮渐变(主题感知) /// 获取买入按钮渐变(主题感知)
static LinearGradient getBuyGradient(bool isDark) => LinearGradient( static LinearGradient getBuyGradient(bool isDark) => LinearGradient(
colors: isDark colors: isDark

View File

@@ -281,7 +281,9 @@ class _NeonButtonState extends State<NeonButton>
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: _gradient, gradient: _gradient,
color: _gradient == null ? _backgroundColor : null, color: _gradient == null ? _backgroundColor : null,
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(
widget.type == NeonButtonType.outline ? AppRadius.md : AppRadius.lg,
),
border: widget.type == NeonButtonType.outline border: widget.type == NeonButtonType.outline
? Border.all( ? Border.all(
color: colorScheme.outlineVariant.withOpacity(0.3), color: colorScheme.outlineVariant.withOpacity(0.3),
@@ -324,7 +326,9 @@ class _NeonButtonState extends State<NeonButton>
if (widget.showGlow && widget.type != NeonButtonType.outline) { if (widget.showGlow && widget.type != NeonButtonType.outline) {
return NeonGlow( return NeonGlow(
glowColor: _glowColor, glowColor: _glowColor,
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(
widget.type == NeonButtonType.outline ? AppRadius.md : AppRadius.lg,
),
child: button, child: button,
); );
} }

View File

@@ -578,7 +578,7 @@ void _showDepositDialog(BuildContext context) {
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -692,7 +692,7 @@ void _showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -917,7 +917,7 @@ void _showWithdrawDialog(BuildContext context, String? balance) {
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
@@ -1113,7 +1113,7 @@ void _showResultDialog(BuildContext context, String title, String? message) {
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -1156,7 +1156,7 @@ void _showKycRequiredDialog(BuildContext context) {
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View File

@@ -1,4 +1,3 @@
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
@@ -96,7 +95,7 @@ class MainPageState extends State<MainPage> {
} }
} }
/// 底部导航栏 - "The Kinetic Vault" 设计风格 /// 底部导航栏 - 专业信任主题
class _BottomNavBar extends StatelessWidget { class _BottomNavBar extends StatelessWidget {
final List<_NavItem> items; final List<_NavItem> items;
final int currentIndex; final int currentIndex;
@@ -114,22 +113,14 @@ class _BottomNavBar extends StatelessWidget {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerLow.withOpacity(0.8), color: colorScheme.surfaceContainerLow,
borderRadius: BorderRadius.vertical(top: Radius.circular(AppRadius.xxl + AppSpacing.sm)), borderRadius: BorderRadius.vertical(top: Radius.circular(AppRadius.xxl + AppSpacing.sm)),
border: Border( border: Border(
top: BorderSide( top: BorderSide(
color: colorScheme.outlineVariant.withOpacity(0.15), color: colorScheme.outlineVariant.withOpacity(0.15),
), ),
), ),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 40, // 阴影效果保持固定
offset: const Offset(0, -10),
), ),
],
),
// 【优化】移除毛玻璃效果,保持简洁的半透明背景
child: SafeArea( child: SafeArea(
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(AppSpacing.md, AppSpacing.sm, AppSpacing.md, AppSpacing.lg), padding: EdgeInsets.fromLTRB(AppSpacing.md, AppSpacing.sm, AppSpacing.md, AppSpacing.lg),
@@ -176,13 +167,6 @@ class _NavItemWidget extends StatelessWidget {
? BoxDecoration( ? BoxDecoration(
color: colorScheme.primary.withOpacity(0.1), color: colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(AppSpacing.md), borderRadius: BorderRadius.circular(AppSpacing.md),
boxShadow: [
BoxShadow(
color: colorScheme.primary.withOpacity(0.3),
blurRadius: 15, // 发光效果保持固定
spreadRadius: 0,
),
],
) )
: null, : null,
child: Column( child: Column(

View File

@@ -265,6 +265,7 @@ class _TradePageState extends State<TradePage>
void _showResultDialog(bool success, String title, String message) { void _showResultDialog(bool success, String title, String message) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showShadDialog( showShadDialog(
context: context, context: context,
builder: (ctx) => ShadDialog.alert( builder: (ctx) => ShadDialog.alert(
@@ -272,7 +273,9 @@ class _TradePageState extends State<TradePage>
children: [ children: [
NeonIcon( NeonIcon(
icon: success ? Icons.check_circle : Icons.error, icon: success ? Icons.check_circle : Icons.error,
color: success ? AppColorScheme.up : colorScheme.error, color: success
? AppColorScheme.getUpColor(isDark)
: colorScheme.error,
size: 24, size: 24,
), ),
SizedBox(width: AppSpacing.sm), SizedBox(width: AppSpacing.sm),
@@ -310,12 +313,15 @@ class _ConfirmDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final actionColor = isBuy ? AppColorScheme.up : AppColorScheme.down; final isDark = Theme.of(context).brightness == Brightness.dark;
final actionColor = isBuy
? AppColorScheme.getUpColor(isDark)
: AppColorScheme.getDownColor(isDark);
return Dialog( return Dialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
child: GlassPanel( child: GlassPanel(
borderRadius: BorderRadius.circular(AppRadius.xxl), borderRadius: BorderRadius.circular(AppRadius.lg),
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -510,8 +516,11 @@ class _CoinSelector extends StatelessWidget {
Widget _buildCoinItem( Widget _buildCoinItem(
Coin coin, BuildContext context, BuildContext sheetContext) { Coin coin, BuildContext context, BuildContext sheetContext) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isSelected = selectedCoin?.code == coin.code; final isSelected = selectedCoin?.code == coin.code;
final changeColor = coin.isUp ? AppColorScheme.up : AppColorScheme.down; final changeColor = coin.isUp
? AppColorScheme.getUpColor(isDark)
: AppColorScheme.getDownColor(isDark);
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
@@ -762,8 +771,11 @@ class _TradeFormCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isBuy = tradeType == 0; final isBuy = tradeType == 0;
final actionColor = isBuy ? AppColorScheme.up : AppColorScheme.down; final actionColor = isBuy
? AppColorScheme.getUpColor(isDark)
: AppColorScheme.getDownColor(isDark);
return GlassPanel( return GlassPanel(
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
@@ -784,7 +796,7 @@ class _TradeFormCard extends StatelessWidget {
context: context, context: context,
label: '买入', label: '买入',
isActive: isBuy, isActive: isBuy,
color: AppColorScheme.up, color: AppColorScheme.buyButtonFill,
icon: LucideIcons.trendingUp, icon: LucideIcons.trendingUp,
onTap: () => onTradeTypeChanged(0), onTap: () => onTradeTypeChanged(0),
), ),
@@ -795,7 +807,7 @@ class _TradeFormCard extends StatelessWidget {
context: context, context: context,
label: '卖出', label: '卖出',
isActive: !isBuy, isActive: !isBuy,
color: AppColorScheme.down, color: AppColorScheme.sellButtonFill,
icon: LucideIcons.trendingDown, icon: LucideIcons.trendingDown,
onTap: () => onTradeTypeChanged(1), onTap: () => onTradeTypeChanged(1),
), ),
@@ -919,7 +931,7 @@ class _TradeFormCard extends StatelessWidget {
); );
} }
/// 买入/卖出切换按钮 - 实心填充 + 图标 + 光效 /// 买入/卖出切换按钮 - 实心填充 + 图标
Widget _buildTypeButton({ Widget _buildTypeButton({
required BuildContext context, required BuildContext context,
required String label, required String label,
@@ -937,15 +949,6 @@ class _TradeFormCard extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: isActive ? color : Colors.transparent, color: isActive ? color : Colors.transparent,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
boxShadow: isActive
? [
BoxShadow(
color: color.withOpacity(0.35),
blurRadius: 16,
offset: const Offset(0, 4),
),
]
: null,
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@@ -1015,11 +1018,8 @@ class _TradeButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark; final fillColor =
final actionColor = isBuy ? AppColorScheme.up : AppColorScheme.down; isBuy ? AppColorScheme.buyButtonFill : AppColorScheme.sellButtonFill;
final gradient = isBuy
? AppColorScheme.getBuyGradient(isDark)
: AppColorScheme.sellGradient;
return GestureDetector( return GestureDetector(
onTap: enabled ? onPressed : null, onTap: enabled ? onPressed : null,
@@ -1027,29 +1027,17 @@ class _TradeButton extends StatelessWidget {
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
height: 52, height: 52,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: enabled ? gradient : null, color: enabled ? fillColor : colorScheme.onSurface.withOpacity(0.08),
color: enabled ? null : colorScheme.onSurface.withOpacity(0.08), borderRadius: BorderRadius.circular(AppRadius.lg),
borderRadius: BorderRadius.circular(AppRadius.xxl),
boxShadow: enabled
? [
BoxShadow(
color: actionColor.withOpacity(isDark ? 0.25 : 0.15),
blurRadius: 20,
offset: const Offset(0, 4),
),
]
: null,
), ),
child: Center( child: Center(
child: isLoading child: isLoading
? SizedBox( ? const SizedBox(
width: 20, width: 20,
height: 20, height: 20,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
color: isBuy color: Colors.white,
? AppColorScheme.darkOnTertiary
: Colors.white,
), ),
) )
: Row( : Row(
@@ -1059,9 +1047,7 @@ class _TradeButton extends StatelessWidget {
isBuy ? LucideIcons.trendingUp : LucideIcons.trendingDown, isBuy ? LucideIcons.trendingUp : LucideIcons.trendingDown,
size: 16, size: 16,
color: enabled color: enabled
? (isBuy ? Colors.white
? AppColorScheme.darkOnTertiary
: Colors.white)
: colorScheme.onSurface.withOpacity(0.3), : colorScheme.onSurface.withOpacity(0.3),
), ),
SizedBox(width: AppSpacing.xs), SizedBox(width: AppSpacing.xs),
@@ -1071,9 +1057,7 @@ class _TradeButton extends StatelessWidget {
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: enabled color: enabled
? (isBuy ? Colors.white
? AppColorScheme.darkOnTertiary
: Colors.white)
: colorScheme.onSurface.withOpacity(0.3), : colorScheme.onSurface.withOpacity(0.3),
letterSpacing: 0.5, letterSpacing: 0.5,
), ),