# Flutter Monisuo 现代化改造规范 v2.0 ## 目标 将 Flutter Monisuo 应用打造为现代化、简约、专业的虚拟货币交易平台,参考 SuperDesign 设计原则。 ## 设计原则 ### 1. 现代化简约风格 - **Vercel/Linear 风格**:干净的深色主题,微妙的阴影,大量留白 - **避免过时设计**:不使用 Bootstrap 蓝、沉重的阴影、复杂的渐变 - **微交互**:细腻的动画反馈(150-400ms) ### 2. 明暗主题支持 - 完整的 Light/Dark 主题切换 - 使用 ColorScheme 管理主题 - 主题切换时平滑过渡 ### 3. 颜色系统(基于 OKLCH 转换) #### 现代深色主题 ```dart // Vercel/Linear 风格 background: Color(0xFF0A0A0B) // oklch(0.098 0.005 270) cardBackground: Color(0xFF111113) // oklch(0.148 0.004 270) primary: Color(0xFF00D4AA) // 品牌青绿色 primaryForeground: Color(0xFFFFFFFF) secondary: Color(0xFF1C1C1F) muted: Color(0xFF27272A) border: Color(0xFF27272A) ``` #### 现代浅色主题 ```dart background: Color(0xFFFFFFFF) // oklch(1 0 0) cardBackground: Color(0xFFFAFAFA) // oklch(0.98 0 0) primary: Color(0xFF00B894) // 品牌青绿色(深色版) primaryForeground: Color(0xFFFFFFFF) secondary: Color(0xFFF4F4F5) muted: Color(0xFFE4E4E7) border: Color(0xFFE4E4E7) ``` #### 涨跌色(明暗通用) ```dart up: Color(0xFF00C853) // 涨/买入(绿色) down: Color(0xFFFF5252) // 跌/卖出(红色) ``` ### 4. 字体系统 #### 使用 Google Fonts ```yaml dependencies: google_fonts: ^6.1.0 ``` #### 字体选择 - **主字体**:Inter(现代、清晰) - **数字字体**:JetBrains Mono(等宽,用于价格/数量) - **回退字体**:system-ui #### 字号系统 ```dart // 标题 displayLarge: 32sp, weight: 700 displayMedium: 24sp, weight: 600 displaySmall: 20sp, weight: 600 // 正文 bodyLarge: 16sp, weight: 400 bodyMedium: 14sp, weight: 400 bodySmall: 12sp, weight: 400 // 数字(等宽) numberLarge: 20sp, JetBrains Mono numberMedium: 16sp, JetBrains Mono numberSmall: 14sp, JetBrains Mono ``` ### 5. 间距系统 ```dart class Spacing { static const double xs = 4.0; // 0.25rem static const double sm = 8.0; // 0.5rem static const double md = 16.0; // 1rem static const double lg = 24.0; // 1.5rem static const double xl = 32.0; // 2rem static const double xxl = 48.0; // 3rem } ``` ### 6. 圆角系统 ```dart class BorderRadius { static const double sm = 4.0; static const double md = 8.0; static const double lg = 12.0; static const double xl = 16.0; static const double xxl = 24.0; static const double full = 9999.0; } ``` ### 7. 阴影系统 ```dart // 微妙的阴影(Vercel 风格) BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 4, offset: Offset(0, 2), ) // 悬停阴影 BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: Offset(0, 4), ) ``` ### 8. 动画系统 ```dart class AnimationDurations { static const Duration fast = Duration(milliseconds: 150); static const Duration normal = Duration(milliseconds: 250); static const Duration slow = Duration(milliseconds: 400); static const Duration verySlow = Duration(milliseconds: 600); } // Curves Curves.easeOutCubic // 入场动画 Curves.easeInOutCubic // 过渡动画 Curves.elasticOut // 弹性反馈 ``` ## 组件设计规范 ### 1. 按钮 #### 主要按钮(Primary) ```dart ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Theme.of(context).colorScheme.onPrimary, minimumSize: Size(44, 44), // 触摸目标 padding: EdgeInsets.symmetric(horizontal: Spacing.lg, vertical: Spacing.md), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(BorderRadius.md), ), elevation: 0, // 现代风格:无阴影或微阴影 ), ) ``` #### 次要按钮(Secondary) ```dart OutlinedButton( style: OutlinedButton.styleFrom( minimumSize: Size(44, 44), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(BorderRadius.md), ), side: BorderSide(color: Theme.of(context).colorScheme.border), ), ) ``` #### 幽灵按钮(Ghost) ```dart TextButton( style: TextButton.styleFrom( minimumSize: Size(44, 44), ), ) ``` ### 2. 卡片 ```dart Card( elevation: 0, // 使用边框代替阴影 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(BorderRadius.lg), side: BorderSide( color: Theme.of(context).colorScheme.border, width: 1, ), ), color: Theme.of(context).colorScheme.cardBackground, child: Padding( padding: EdgeInsets.all(Spacing.md), child: Column(...), ), ) ``` ### 3. 输入框 ```dart TextFormField( decoration: InputDecoration( filled: true, fillColor: Theme.of(context).colorScheme.cardBackground, border: OutlineInputBorder( borderRadius: BorderRadius.circular(BorderRadius.md), borderSide: BorderSide(color: Theme.of(context).colorScheme.border), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(BorderRadius.md), borderSide: BorderSide(color: Theme.of(context).colorScheme.border), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(BorderRadius.md), borderSide: BorderSide( color: Theme.of(context).colorScheme.primary, width: 2, ), ), contentPadding: EdgeInsets.symmetric( horizontal: Spacing.md, vertical: Spacing.sm, ), ), ) ``` ### 4. 现代弹窗 #### 标准弹窗 ```dart showDialog( context: context, builder: (context) => Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(BorderRadius.xl), ), backgroundColor: Theme.of(context).colorScheme.cardBackground, child: Container( padding: EdgeInsets.all(Spacing.lg), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题 Text( 'Dialog Title', style: Theme.of(context).textTheme.displaySmall, ), SizedBox(height: Spacing.md), // 内容 Text('Dialog content here...'), SizedBox(height: Spacing.lg), // 按钮 Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton(child: Text('Cancel')), SizedBox(width: Spacing.sm), ElevatedButton(child: Text('Confirm')), ], ), ], ), ), ), ); ``` #### 底部抽屉(Bottom Sheet) ```dart showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => Container( decoration: BoxDecoration( color: Theme.of(context).colorScheme.cardBackground, borderRadius: BorderRadius.vertical( top: Radius.circular(BorderRadius.xl), ), ), padding: EdgeInsets.all(Spacing.lg), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 拖动指示器 Container( width: 40, height: 4, decoration: BoxDecoration( color: Theme.of(context).colorScheme.muted, borderRadius: BorderRadius.circular(2), ), ), SizedBox(height: Spacing.md), // 内容 ... ], ), ), ); ``` ### 5. 列表项 ```dart ListTile( contentPadding: EdgeInsets.symmetric( horizontal: Spacing.md, vertical: Spacing.sm, ), leading: Container( width: 40, height: 40, decoration: BoxDecoration( color: Theme.of(context).colorScheme.secondary, borderRadius: BorderRadius.circular(BorderRadius.md), ), child: Icon(icon, size: 20), ), title: Text( title, style: Theme.of(context).textTheme.bodyLarge, ), subtitle: Text( subtitle, style: Theme.of(context).textTheme.bodySmall, ), trailing: Icon(Icons.chevron_right, size: 20), ) ``` ## 页面布局规范 ### 1. 通用布局 ```dart Scaffold( backgroundColor: Theme.of(context).colorScheme.background, appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.background, elevation: 0, title: Text('Page Title'), ), body: SafeArea( child: SingleChildScrollView( padding: EdgeInsets.all(Spacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 内容 ], ), ), ), ) ``` ### 2. 响应式布局 ```dart LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth >= 1024) { // 桌面布局 return _DesktopLayout(); } else if (constraints.maxWidth >= 768) { // 平板布局 return _TabletLayout(); } else { // 移动布局 return _MobileLayout(); } }, ) ``` ## 主题切换实现 ### 1. 主题 Provider ```dart class ThemeProvider extends ChangeNotifier { ThemeMode _themeMode = ThemeMode.system; ThemeMode get themeMode => _themeMode; void toggleTheme() { _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; notifyListeners(); } void setTheme(ThemeMode mode) { _themeMode = mode; notifyListeners(); } } ``` ### 2. 主题切换按钮 ```dart IconButton( icon: Icon( Provider.of(context).themeMode == ThemeMode.light ? Icons.dark_mode : Icons.light_mode, ), onPressed: () { Provider.of(context, listen: false).toggleTheme(); }, ) ``` ## 无障碍设计 ### 1. 对比度 - 所有文字/背景组合 >= 4.5:1(WCAG AA) - 大文字(18sp+)>= 3:1 ### 2. 触摸目标 - 最小触摸目标 44x44 ### 3. 语义化 ```dart Semantics( label: 'Submit button', button: true, child: ElevatedButton(...), ) ``` ## 禁止事项 - ❌ 使用过时的 Bootstrap 蓝 (#007bff) - ❌ 沉重的阴影 - ❌ 复杂的渐变 - ❌ 文字与背景颜色相同 - ❌ 对比度 < 4.5:1 - ❌ 触摸目标 < 44x44 - ❌ 硬编码颜色值 - ❌ 不一致的间距/圆角 ## 验证清单 - [ ] 明暗主题切换正常 - [ ] 所有页面风格一致 - [ ] 对比度 >= 4.5:1 - [ ] 触摸目标 >= 44x44 - [ ] flutter analyze 无错误 - [ ] 响应式布局正常 - [ ] 动画流畅(60fps) - [ ] 无硬编码颜色 - [ ] 间距/圆角一致