snap_wish/lib/core/theme/app_theme.dart
2025-09-17 11:42:38 +08:00

356 lines
13 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/// 应用主题配置类 - 管理应用的主题样式和色彩方案
/// 支持浅色主题、深色主题和系统跟随模式
class AppTheme {
// 私有构造函数,防止实例化
AppTheme._();
/// 主题色彩配置
static const Color primaryColor = Color(0xFF2196F3);
static const Color secondaryColor = Color(0xFF03DAC6);
static const Color backgroundColor = Color(0xFFF5F5F5);
static const Color surfaceColor = Colors.white;
static const Color errorColor = Color(0xFFB00020);
/// 文字颜色
static const Color textPrimary = Color(0xFF212121);
static const Color textSecondary = Color(0xFF757575);
static const Color textHint = Color(0xFFBDBDBD);
/// 边框和分割线颜色
static const Color dividerColor = Color(0xFFE0E0E0);
static const Color borderColor = Color(0xFFCCCCCC);
/// 浅色主题
static ThemeData lightTheme = ThemeData(
useMaterial3: true,
brightness: Brightness.light,
primaryColor: primaryColor,
colorScheme: const ColorScheme.light(
primary: primaryColor,
secondary: secondaryColor,
surface: surfaceColor,
background: backgroundColor,
error: errorColor,
onPrimary: Colors.white,
onSecondary: Colors.black,
onSurface: textPrimary,
onBackground: textPrimary,
onError: Colors.white,
),
// 应用栏主题
appBarTheme: const AppBarTheme(
backgroundColor: surfaceColor,
foregroundColor: textPrimary,
elevation: 0,
centerTitle: true,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
),
),
// 卡片主题
cardTheme: CardTheme(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
margin: const EdgeInsets.all(8.0),
),
// 按钮主题
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
),
// 输入框主题
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: Colors.grey[100],
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: borderColor),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: borderColor),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: primaryColor, width: 2.0),
),
contentPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
// 文字主题
textTheme: const TextTheme(
displayLarge: TextStyle(fontSize: 57.0, fontWeight: FontWeight.w400, color: textPrimary),
displayMedium: TextStyle(fontSize: 45.0, fontWeight: FontWeight.w400, color: textPrimary),
displaySmall: TextStyle(fontSize: 36.0, fontWeight: FontWeight.w400, color: textPrimary),
headlineLarge: TextStyle(fontSize: 32.0, fontWeight: FontWeight.w400, color: textPrimary),
headlineMedium: TextStyle(fontSize: 28.0, fontWeight: FontWeight.w400, color: textPrimary),
headlineSmall: TextStyle(fontSize: 24.0, fontWeight: FontWeight.w400, color: textPrimary),
titleLarge: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w400, color: textPrimary),
titleMedium: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500, color: textPrimary),
titleSmall: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: textPrimary),
bodyLarge: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400, color: textPrimary),
bodyMedium: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400, color: textPrimary),
bodySmall: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w400, color: textSecondary),
labelLarge: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: textPrimary),
labelMedium: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w500, color: textPrimary),
labelSmall: TextStyle(fontSize: 11.0, fontWeight: FontWeight.w500, color: textPrimary),
),
// 图标主题
iconTheme: const IconThemeData(
color: textSecondary,
size: 24.0,
),
// 分割线主题
dividerTheme: const DividerThemeData(
color: dividerColor,
thickness: 1.0,
space: 0,
),
);
/// 深色主题
static ThemeData darkTheme = ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
primaryColor: primaryColor,
colorScheme: const ColorScheme.dark(
primary: primaryColor,
secondary: secondaryColor,
surface: Color(0xFF121212),
background: Color(0xFF121212),
error: errorColor,
onPrimary: Colors.white,
onSecondary: Colors.black,
onSurface: Colors.white,
onBackground: Colors.white,
onError: Colors.white,
),
// 应用栏主题(深色模式保持一定对比度)
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF1E1E1E),
foregroundColor: Colors.white,
elevation: 0,
centerTitle: true,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
),
),
// 卡片主题
cardTheme: CardTheme(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
margin: const EdgeInsets.all(8.0),
color: const Color(0xFF1E1E1E),
),
// 按钮主题
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
backgroundColor: primaryColor,
foregroundColor: Colors.white,
),
),
// 输入框主题
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: const Color(0xFF2C2C2C),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: Color(0xFF3C3C3C)),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: Color(0xFF3C3C3C)),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: const BorderSide(color: primaryColor, width: 2.0),
),
contentPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
// 文字主题(深色模式保持可读性)
textTheme: const TextTheme(
displayLarge: TextStyle(fontSize: 57.0, fontWeight: FontWeight.w400, color: Colors.white),
displayMedium: TextStyle(fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.white),
displaySmall: TextStyle(fontSize: 36.0, fontWeight: FontWeight.w400, color: Colors.white),
headlineLarge: TextStyle(fontSize: 32.0, fontWeight: FontWeight.w400, color: Colors.white),
headlineMedium: TextStyle(fontSize: 28.0, fontWeight: FontWeight.w400, color: Colors.white),
headlineSmall: TextStyle(fontSize: 24.0, fontWeight: FontWeight.w400, color: Colors.white),
titleLarge: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w400, color: Colors.white),
titleMedium: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500, color: Colors.white),
titleSmall: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white),
bodyLarge: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400, color: Colors.white),
bodyMedium: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400, color: Colors.white),
bodySmall: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w400, color: Color(0xFFB0B0B0)),
labelLarge: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white),
labelMedium: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w500, color: Colors.white),
labelSmall: TextStyle(fontSize: 11.0, fontWeight: FontWeight.w500, color: Colors.white),
),
// 图标主题
iconTheme: const IconThemeData(
color: Color(0xFFB0B0B0),
size: 24.0,
),
// 分割线主题
dividerTheme: const DividerThemeData(
color: Color(0xFF3C3C3C),
thickness: 1.0,
space: 0,
),
);
/// 获取主题模式对应的主题数据
static ThemeData getTheme(Brightness brightness) {
return brightness == Brightness.dark ? darkTheme : lightTheme;
}
/// 获取当前主题的对比色(用于保证可读性)
static Color getContrastColor(Color backgroundColor) {
// 计算颜色的亮度
final brightness = backgroundColor.computeLuminance();
// 亮度大于0.5使用深色,否则使用浅色
return brightness > 0.5 ? Colors.black : Colors.white;
}
}
/// 应用色彩配置类 - 定义应用使用的颜色常量
/// 提供浅色和深色主题下的颜色配置
class AppColors {
/// 主色调 - 应用的主要品牌色彩
static const Color primary = Color(0xFF2196F3);
/// 主色调上的文本色彩 - 用于主色调背景上的文本
static const Color onPrimary = Color(0xFFFFFFFF);
/// 次要色调 - 用于次要操作或强调
static const Color secondary = Color(0xFF03DAC6);
/// 次要色调上的文本色彩 - 用于次要色调背景上的文本
static const Color onSecondary = Color(0xFF000000);
/// 错误色调 - 用于错误提示、危险操作等
static const Color error = Color(0xFFB00020);
/// 错误色调上的文本色彩 - 用于错误色调背景上的文本
static const Color onError = Color(0xFFFFFFFF);
/// 背景色彩 - 应用的主要背景色
static const Color background = Color(0xFFF5F5F5);
/// 背景上的文本色彩 - 用于背景上的主要文本
static const Color onBackground = Color(0xFF212121);
/// 表面色彩 - 卡片、对话框等组件的背景色
static const Color surface = Color(0xFFFFFFFF);
/// 表面上的文本色彩 - 用于表面上的主要文本
static const Color onSurface = Color(0xFF212121);
/// 表面变体色彩 - 用于区分不同层次的表面
static const Color surfaceVariant = Color(0xFFE0E0E0);
/// 表面变体上的文本色彩 - 用于表面变体上的文本
static const Color onSurfaceVariant = Color(0xFF616161);
/// 轮廓色彩 - 用于边框、分割线等
static const Color outline = Color(0xFFBDBDBD);
/// 成功色彩 - 用于成功提示、完成状态等
static const Color success = Color(0xFF4CAF50);
/// 警告色彩 - 用于警告提示、注意状态等
static const Color warning = Color(0xFFFF9800);
/// 信息色彩 - 用于信息提示、说明状态等
static const Color info = Color(0xFF2196F3);
/// 禁用状态色彩 - 用于禁用状态的组件
static const Color disabled = Color(0xFFBDBDBD);
/// 加载状态色彩 - 用于加载指示器
static const Color loading = Color(0xFF2196F3);
/// 透明色彩 - 用于需要透明的场景
static const Color transparent = Color(0x00000000);
/// 阴影色彩 - 用于阴影效果
static const Color shadow = Color(0x1F000000);
/// 从BuildContext获取颜色配置 - 便捷方法获取当前主题颜色
static AppColors of(BuildContext context) {
// 这里可以根据主题亮度返回不同的颜色配置
// 目前返回默认的颜色配置
return AppColors();
}
/// 创建浅色主题颜色方案
static ColorScheme get lightColorScheme {
return const ColorScheme.light(
primary: primary,
onPrimary: onPrimary,
secondary: secondary,
onSecondary: onSecondary,
error: error,
onError: onError,
background: background,
onBackground: onBackground,
surface: surface,
onSurface: onSurface,
surfaceVariant: surfaceVariant,
onSurfaceVariant: onSurfaceVariant,
outline: outline,
);
}
/// 创建深色主题颜色方案
static ColorScheme get darkColorScheme {
return const ColorScheme.dark(
primary: primary,
onPrimary: onPrimary,
secondary: secondary,
onSecondary: onSecondary,
error: error,
onError: onError,
background: Color(0xFF121212),
onBackground: Color(0xFFFFFFFF),
surface: Color(0xFF1E1E1E),
onSurface: Color(0xFFFFFFFF),
surfaceVariant: Color(0xFF2C2C2C),
onSurfaceVariant: Color(0xFFBDBDBD),
outline: Color(0xFF424242),
);
}
}