feat: 优化
This commit is contained in:
@@ -1,461 +0,0 @@
|
|||||||
# 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<ThemeProvider>(context).themeMode == ThemeMode.light
|
|
||||||
? Icons.dark_mode
|
|
||||||
: Icons.light_mode,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
Provider.of<ThemeProvider>(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)
|
|
||||||
- [ ] 无硬编码颜色
|
|
||||||
- [ ] 间距/圆角一致
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
# 数字货币应用主题设计规范
|
|
||||||
|
|
||||||
## 设计原则
|
|
||||||
|
|
||||||
1. **一致性** - 所有页面使用统一的设计语言
|
|
||||||
2. **可读性** - 确保文字与背景对比度充足 (WCAG AA 标准)
|
|
||||||
3. **响应式** - 适配不同屏幕尺寸
|
|
||||||
4. **专业性** - 符合金融/交易类应用的专业感
|
|
||||||
5. **无障碍** - 避免颜色冲突,支持色盲用户
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 颜色系统
|
|
||||||
|
|
||||||
### 主色调 (Primary)
|
|
||||||
|
|
||||||
```
|
|
||||||
主色: #00D4AA (青绿色 - 代表增长、积极)
|
|
||||||
主色浅: #00E6B8
|
|
||||||
主色深: #00B894
|
|
||||||
```
|
|
||||||
|
|
||||||
### 涨跌色 (Trading Colors)
|
|
||||||
|
|
||||||
```
|
|
||||||
涨/买入: #00C853 (标准绿 - 国际通用)
|
|
||||||
跌/卖出: #FF5252 (标准红 - 国际通用)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 背景色 (Dark Theme)
|
|
||||||
|
|
||||||
```
|
|
||||||
背景主色: #0F0F1A (深蓝黑)
|
|
||||||
卡片背景: #1A1A2E (深蓝紫)
|
|
||||||
输入框背景: #16213E (深蓝)
|
|
||||||
模态框背景: #1E1E32
|
|
||||||
```
|
|
||||||
|
|
||||||
### 文字颜色
|
|
||||||
|
|
||||||
```
|
|
||||||
主要文字: #FFFFFF (白色)
|
|
||||||
次要文字: #B0B0C0 (灰蓝)
|
|
||||||
提示文字: #6B6B80 (暗灰)
|
|
||||||
禁用文字: #4A4A5A
|
|
||||||
链接文字: #00D4AA
|
|
||||||
```
|
|
||||||
|
|
||||||
### 边框与分割线
|
|
||||||
|
|
||||||
```
|
|
||||||
边框: rgba(255, 255, 255, 0.08)
|
|
||||||
分割线: rgba(255, 255, 255, 0.06)
|
|
||||||
聚焦边框: #00D4AA
|
|
||||||
```
|
|
||||||
|
|
||||||
### 功能色
|
|
||||||
|
|
||||||
```
|
|
||||||
成功: #00C853
|
|
||||||
警告: #FF9800
|
|
||||||
错误: #FF5252
|
|
||||||
信息: #2196F3
|
|
||||||
充值: #00C853
|
|
||||||
提现: #FF9800
|
|
||||||
划转: #2196F3
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 间距系统
|
|
||||||
|
|
||||||
```dart
|
|
||||||
static const double xs = 4.0;
|
|
||||||
static const double sm = 8.0;
|
|
||||||
static const double md = 16.0;
|
|
||||||
static const double lg = 24.0;
|
|
||||||
static const double xl = 32.0;
|
|
||||||
static const double xxl = 48.0;
|
|
||||||
```
|
|
||||||
|
|
||||||
## 圆角系统
|
|
||||||
|
|
||||||
```dart
|
|
||||||
static const double sm = 8.0; // 小组件
|
|
||||||
static const double md = 12.0; // 按钮、输入框
|
|
||||||
static const double lg = 16.0; // 卡片
|
|
||||||
static const double xl = 24.0; // 大卡片
|
|
||||||
static const double full = 999.0; // 圆形
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 文字排版
|
|
||||||
|
|
||||||
### 字号
|
|
||||||
|
|
||||||
```
|
|
||||||
h1: 28px - 页面大标题
|
|
||||||
h2: 24px - 区块标题
|
|
||||||
h3: 20px - 卡片标题
|
|
||||||
h4: 18px - 小标题
|
|
||||||
body1: 16px - 正文
|
|
||||||
body2: 14px - 次要正文
|
|
||||||
caption: 12px - 辅助文字
|
|
||||||
small: 11px - 极小文字
|
|
||||||
```
|
|
||||||
|
|
||||||
### 字重
|
|
||||||
|
|
||||||
```
|
|
||||||
bold: 700 (标题)
|
|
||||||
semibold: 600 (强调)
|
|
||||||
medium: 500 (正文)
|
|
||||||
regular: 400 (辅助)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 组件规范
|
|
||||||
|
|
||||||
### 按钮
|
|
||||||
|
|
||||||
1. **主按钮**
|
|
||||||
- 高度: 48px
|
|
||||||
- 圆角: 12px
|
|
||||||
- 背景: 主题色渐变
|
|
||||||
- 文字: 白色, 16px, semibold
|
|
||||||
|
|
||||||
2. **买入按钮**
|
|
||||||
- 背景: #00C853 渐变
|
|
||||||
- 文字: 白色
|
|
||||||
|
|
||||||
3. **卖出按钮**
|
|
||||||
- 背景: #FF5252 渐变
|
|
||||||
- 文字: 白色
|
|
||||||
|
|
||||||
4. **轮廓按钮**
|
|
||||||
- 边框: 1px solid border
|
|
||||||
- 背景: 透明
|
|
||||||
- 文字: 主题色
|
|
||||||
|
|
||||||
### 输入框
|
|
||||||
|
|
||||||
- 高度: 48px
|
|
||||||
- 圆角: 12px
|
|
||||||
- 背景: #16213E
|
|
||||||
- 边框: 1px solid rgba(255,255,255,0.1)
|
|
||||||
- 聚焦边框: #00D4AA
|
|
||||||
- 文字: 白色
|
|
||||||
- 提示: #6B6B80
|
|
||||||
|
|
||||||
### 卡片
|
|
||||||
|
|
||||||
- 圆角: 16px
|
|
||||||
- 背景: #1A1A2E
|
|
||||||
- 内边距: 16px-20px
|
|
||||||
- 阴影: 无 (扁平设计)
|
|
||||||
|
|
||||||
### 涨跌标签
|
|
||||||
|
|
||||||
- 圆角: 6px
|
|
||||||
- 内边距: 6px 10px
|
|
||||||
- 涨: 背景 rgba(0,200,83,0.15), 文字 #00C853
|
|
||||||
- 跌: 背景 rgba(255,82,82,0.15), 文字 #FF5252
|
|
||||||
|
|
||||||
### 底部导航
|
|
||||||
|
|
||||||
- 高度: 60px + safeArea
|
|
||||||
- 背景: #0F0F1A
|
|
||||||
- 边框: top 1px solid rgba(255,255,255,0.08)
|
|
||||||
- 选中色: #00D4AA
|
|
||||||
- 未选中色: #6B6B80
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 响应式断点
|
|
||||||
|
|
||||||
```dart
|
|
||||||
// 手机竖屏
|
|
||||||
const double mobile = 360;
|
|
||||||
|
|
||||||
// 手机横屏/小平板
|
|
||||||
const double tablet = 768;
|
|
||||||
|
|
||||||
// 平板/桌面
|
|
||||||
const double desktop = 1024;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 动画规范
|
|
||||||
|
|
||||||
- 标准时长: 200ms-300ms
|
|
||||||
- 缓动曲线: easeOutCubic
|
|
||||||
- 页面转场: 300ms
|
|
||||||
- 按钮反馈: 150ms
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 无障碍设计
|
|
||||||
|
|
||||||
1. **对比度**: 所有文字与背景对比度 >= 4.5:1
|
|
||||||
2. **触摸目标**: 最小 44x44px
|
|
||||||
3. **状态反馈**: 不仅依赖颜色区分
|
|
||||||
4. **焦点指示**: 明显的焦点样式
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 禁止事项
|
|
||||||
|
|
||||||
1. ❌ 文字与背景颜色相同
|
|
||||||
2. ❌ 纯黑色背景 (#000000)
|
|
||||||
3. ❌ 纯白色文字在浅色背景
|
|
||||||
4. ❌ 低对比度组合 (对比度 < 4.5)
|
|
||||||
5. ❌ 仅用颜色区分状态
|
|
||||||
6. ❌ 过小的触摸目标 (< 44px)
|
|
||||||
7. ❌ 不一致的组件样式
|
|
||||||
8. ❌ 硬编码颜色值
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 实现清单
|
|
||||||
|
|
||||||
### 核心文件
|
|
||||||
|
|
||||||
1. `lib/core/theme/app_colors.dart` - 颜色定义
|
|
||||||
2. `lib/core/theme/app_theme.dart` - 主题配置
|
|
||||||
3. `lib/core/theme/app_text_styles.dart` - 文字样式
|
|
||||||
4. `lib/core/theme/app_spacing.dart` - 间距常量
|
|
||||||
5. `lib/ui/shared/ui_constants.dart` - 整合导出
|
|
||||||
|
|
||||||
### 需要优化的文件
|
|
||||||
|
|
||||||
- 所有 UI 页面文件
|
|
||||||
- 所有 UI 组件文件
|
|
||||||
- main.dart 主题配置
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
# Monisuo Flutter 主题现代化规范
|
|
||||||
|
|
||||||
## 项目概况
|
|
||||||
|
|
||||||
- **项目名称**: flutter_monisuo (虚拟货币模拟交易平台)
|
|
||||||
- **技术栈**: Flutter 3 + Dart + shadcn_ui 0.52.1
|
|
||||||
- **当前状态**: 已集成 shadcn_ui,部分页面已重构
|
|
||||||
|
|
||||||
## 现代化目标
|
|
||||||
|
|
||||||
### 1. 统一设计系统
|
|
||||||
|
|
||||||
#### 1.1 主题配置
|
|
||||||
- 当前:Slate 深色主题
|
|
||||||
- 目标:
|
|
||||||
- 统一配色方案(品牌色、涨跌色、中性色)
|
|
||||||
- 完善的深色/浅色模式支持
|
|
||||||
- 自定义品牌色系统
|
|
||||||
|
|
||||||
#### 1.2 间距系统
|
|
||||||
- 标准化 padding/margin/gap
|
|
||||||
- 使用统一的间距 token
|
|
||||||
- 响应式布局适配
|
|
||||||
|
|
||||||
#### 1.3 组件样式
|
|
||||||
- 所有按钮统一使用 ShadButton
|
|
||||||
- 所有卡片统一使用 ShadCard
|
|
||||||
- 所有输入框统一使用 ShadInputFormField
|
|
||||||
- 所有图标统一使用 LucideIcons
|
|
||||||
|
|
||||||
### 2. 页面现代化
|
|
||||||
|
|
||||||
#### 2.1 核心页面(高优先级)
|
|
||||||
1. **首页 (home_page.dart)**
|
|
||||||
- 使用 ShadCard 展示资产概览
|
|
||||||
- 使用 ShadButton 进行快捷操作
|
|
||||||
- 添加 flutter_animate 动画
|
|
||||||
|
|
||||||
2. **行情页面 (market_page.dart)**
|
|
||||||
- 币种列表使用 ShadCard
|
|
||||||
- 价格变化使用 ShadBadge
|
|
||||||
- 搜索框使用 ShadInput
|
|
||||||
|
|
||||||
3. **交易页面 (trade_page.dart)**
|
|
||||||
- 买入/卖出使用不同颜色的 ShadButton
|
|
||||||
- 数量输入使用 ShadInputFormField
|
|
||||||
- 币种选择使用 ShadSelect
|
|
||||||
|
|
||||||
4. **资产页面 (asset_page.dart)**
|
|
||||||
- 总资产使用大号 ShadCard
|
|
||||||
- 充值/提现使用 ShadButton
|
|
||||||
- 资金列表使用 ShadListTile
|
|
||||||
|
|
||||||
5. **个人中心 (mine_page.dart)**
|
|
||||||
- 菜单项使用统一布局
|
|
||||||
- 设置项使用 ShadSwitch
|
|
||||||
- 退出登录使用 ShadButton.destructive
|
|
||||||
|
|
||||||
#### 2.2 认证页面(中优先级)
|
|
||||||
1. **登录页面 (login_page.dart)**
|
|
||||||
- 已有示例:login_page_shadcn.dart
|
|
||||||
- 需要替换原文件
|
|
||||||
|
|
||||||
2. **注册页面 (register_page.dart)**
|
|
||||||
- 创建 shadcn 版本
|
|
||||||
- 完整表单验证
|
|
||||||
|
|
||||||
#### 2.3 主框架(高优先级)
|
|
||||||
1. **主页面 (main_page.dart)**
|
|
||||||
- 已有示例:main_page_shadcn.dart
|
|
||||||
- 需要替换原文件
|
|
||||||
- 优化底部导航
|
|
||||||
|
|
||||||
### 3. 自定义组件
|
|
||||||
|
|
||||||
创建业务特定组件:
|
|
||||||
|
|
||||||
#### 3.1 CoinCard - 币种卡片
|
|
||||||
```dart
|
|
||||||
class CoinCard extends StatelessWidget {
|
|
||||||
final String name;
|
|
||||||
final String code;
|
|
||||||
final double price;
|
|
||||||
final double change24h;
|
|
||||||
final String iconUrl;
|
|
||||||
|
|
||||||
// 使用 ShadCard + ShadAvatar + ShadBadge
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.2 TradeButton - 交易按钮
|
|
||||||
```dart
|
|
||||||
class TradeButton extends StatelessWidget {
|
|
||||||
final bool isBuy;
|
|
||||||
final VoidCallback onPressed;
|
|
||||||
|
|
||||||
// 买入:绿色 ShadButton
|
|
||||||
// 卖出:红色 ShadButton.destructive
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.3 AssetCard - 资产卡片
|
|
||||||
```dart
|
|
||||||
class AssetCard extends StatelessWidget {
|
|
||||||
final String title;
|
|
||||||
final double balance;
|
|
||||||
final double change;
|
|
||||||
|
|
||||||
// 使用 ShadCard + 大号文本
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.4 PriceChart - 价格图表
|
|
||||||
```dart
|
|
||||||
class PriceChart extends StatelessWidget {
|
|
||||||
final List<double> prices;
|
|
||||||
final bool isUp;
|
|
||||||
|
|
||||||
// 使用 flutter_animate 添加动画
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 动画系统
|
|
||||||
|
|
||||||
使用 flutter_animate 添加动画:
|
|
||||||
|
|
||||||
#### 4.1 页面切换动画
|
|
||||||
- 淡入淡出
|
|
||||||
- 滑动效果
|
|
||||||
|
|
||||||
#### 4.2 列表加载动画
|
|
||||||
- 交错淡入
|
|
||||||
- 滑动进入
|
|
||||||
|
|
||||||
#### 4.3 交互反馈动画
|
|
||||||
- 按钮点击缩放
|
|
||||||
- 卡片悬停效果
|
|
||||||
|
|
||||||
### 5. 主题定制
|
|
||||||
|
|
||||||
#### 5.1 品牌色系统
|
|
||||||
```dart
|
|
||||||
// 自定义品牌色
|
|
||||||
const brandGreen = Color(0xFF00D4AA); // 品牌绿
|
|
||||||
const upColor = Color(0xFF10B981); // 涨
|
|
||||||
const downColor = Color(0xFFEF4444); // 跌
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 5.2 配色方案选择
|
|
||||||
- **Slate**(当前):专业、稳重
|
|
||||||
- 可选:Zinc(现代)、Blue(活力)
|
|
||||||
|
|
||||||
## 禁止事项
|
|
||||||
|
|
||||||
- ❌ 不要修改业务逻辑
|
|
||||||
- ❌ 不要修改 API 调用
|
|
||||||
- ❌ 不要修改数据模型
|
|
||||||
- ❌ 不要删除现有功能
|
|
||||||
- ❌ 不要改变 Provider 逻辑
|
|
||||||
|
|
||||||
## 验证标准
|
|
||||||
|
|
||||||
### 功能验证
|
|
||||||
- [ ] 用户可以登录/注册
|
|
||||||
- [ ] 可以查看行情
|
|
||||||
- [ ] 可以进行交易
|
|
||||||
- [ ] 可以查看资产
|
|
||||||
- [ ] 可以修改设置
|
|
||||||
|
|
||||||
### 视觉验证
|
|
||||||
- [ ] 所有页面使用统一的组件
|
|
||||||
- [ ] 所有页面有一致的间距
|
|
||||||
- [ ] 所有页面有流畅的动画
|
|
||||||
- [ ] 深色模式完美支持
|
|
||||||
|
|
||||||
### 代码验证
|
|
||||||
- [ ] 无 Dart 分析错误
|
|
||||||
- [ ] 无 Flutter 警告
|
|
||||||
- [ ] 构建成功
|
|
||||||
- [ ] 无运行时错误
|
|
||||||
|
|
||||||
## 重构优先级
|
|
||||||
|
|
||||||
### P0 - 立即执行
|
|
||||||
1. 替换 main_page.dart 为 shadcn 版本
|
|
||||||
2. 替换 login_page.dart 为 shadcn 版本
|
|
||||||
3. 重构 home_page.dart
|
|
||||||
|
|
||||||
### P1 - 高优先级
|
|
||||||
1. 重构 market_page.dart
|
|
||||||
2. 重构 trade_page.dart
|
|
||||||
3. 重构 asset_page.dart
|
|
||||||
|
|
||||||
### P2 - 中优先级
|
|
||||||
1. 重构 mine_page.dart
|
|
||||||
2. 重构 register_page.dart
|
|
||||||
3. 创建自定义组件
|
|
||||||
|
|
||||||
### P3 - 低优先级
|
|
||||||
1. 优化动画
|
|
||||||
2. 添加高级效果
|
|
||||||
3. 性能优化
|
|
||||||
|
|
||||||
## 参考资源
|
|
||||||
|
|
||||||
- [shadcn_ui Flutter 文档](https://flutter-shadcn-ui.mariuti.com/)
|
|
||||||
- [Lucide Icons Flutter](https://pub.dev/packages/lucide_icons_flutter)
|
|
||||||
- [flutter_animate](https://pub.dev/packages/flutter_animate)
|
|
||||||
- [REFACTOR_PLAN.md](../REFACTOR_PLAN.md) - 已有的重构计划
|
|
||||||
Reference in New Issue
Block a user