436 lines
14 KiB
Dart
436 lines
14 KiB
Dart
import 'package:flutter/material.dart';
|
||
|
||
/// SocialChat马甲包独立主题系统
|
||
/// 定义完全独立的视觉设计语言,与原始应用区分
|
||
|
||
class SocialChatTheme {
|
||
// 主色调色板 (橙色主题)
|
||
static const Color primaryColor = Color(0xff18F2B1); // 主色 - 橙色
|
||
static const Color primaryLight = Color(0xff18F2B1); // 浅橙色
|
||
static const Color primaryDark = Color(0xffC41C00); // 深橙色
|
||
|
||
// 次要颜色
|
||
static const Color secondaryColor = Color(0xff2196F3); // 蓝色作为强调色
|
||
static const Color secondaryLight = Color(0xff6EC6FF);
|
||
static const Color secondaryDark = Color(0xff0069C0);
|
||
|
||
// 中性色
|
||
static const Color backgroundColor = Color(0xffF8F9FA); // 背景色
|
||
static const Color surfaceColor = Color(0xffffffff); // 表面色
|
||
static const Color errorColor = Color(0xffF44336); // 错误色
|
||
|
||
// 文本颜色
|
||
static const Color textPrimary = Color(0xffffffff);
|
||
static const Color textSecondary = Color(0xff8c8b8b);
|
||
static const Color textDisabled = Color(0xffBDBDBD);
|
||
static const Color textOnPrimary = Color(0xffffffff); // 主色上的文本
|
||
static const Color textOnSecondary = Color(0xffffffff); // 次色上的文本
|
||
|
||
// 边框和分隔线
|
||
static const Color dividerColor = Color(0xffEEEEEE);
|
||
static const Color borderColor = Colors.transparent;
|
||
|
||
// 功能颜色
|
||
static const Color successColor = Color(0xff4CAF50);
|
||
static const Color warningColor = Color(0xffFF9800);
|
||
static const Color infoColor = Color(0xff2196F3);
|
||
|
||
// 透明度
|
||
static const Color transparent = Colors.transparent;
|
||
|
||
// 阴影
|
||
static List<BoxShadow> get cardShadow => [
|
||
BoxShadow(
|
||
color: Colors.black.withOpacity(0.08),
|
||
blurRadius: 12,
|
||
offset: const Offset(0, 4),
|
||
),
|
||
];
|
||
|
||
static List<BoxShadow> get buttonShadow => [
|
||
BoxShadow(
|
||
color: primaryColor.withOpacity(0.3),
|
||
blurRadius: 8,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
];
|
||
|
||
// 间距系统 (基于8px网格)
|
||
static const double spacingXS = 4.0;
|
||
static const double spacingS = 8.0;
|
||
static const double spacingM = 16.0;
|
||
static const double spacingL = 24.0;
|
||
static const double spacingXL = 32.0;
|
||
static const double spacingXXL = 48.0;
|
||
|
||
// 圆角系统
|
||
static const double borderRadiusXS = 4.0;
|
||
static const double borderRadiusS = 8.0;
|
||
static const double borderRadiusM = 12.0;
|
||
static const double borderRadiusL = 16.0;
|
||
static const double borderRadiusXL = 24.0;
|
||
static const double borderRadiusCircle = 50.0;
|
||
|
||
// 字体
|
||
static const String fontFamily = 'Roboto'; // 使用Roboto字体,与原始应用区分
|
||
static const String fontFamilyFallback = 'sans-serif';
|
||
|
||
// 文字样式
|
||
static TextStyle get displayLarge => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 32,
|
||
fontWeight: FontWeight.w700,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get displayMedium => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 28,
|
||
fontWeight: FontWeight.w600,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get displaySmall => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 24,
|
||
fontWeight: FontWeight.w600,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get headlineMedium => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 20,
|
||
fontWeight: FontWeight.w600,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get headlineSmall => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 18,
|
||
fontWeight: FontWeight.w600,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get titleLarge => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get titleMedium => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w500,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get titleSmall => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.w500,
|
||
color: textSecondary,
|
||
);
|
||
|
||
static TextStyle get bodyLarge => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w400,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get bodyMedium => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w400,
|
||
color: textPrimary,
|
||
);
|
||
|
||
static TextStyle get bodySmall => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.w400,
|
||
color: textSecondary,
|
||
);
|
||
|
||
static TextStyle get labelLarge => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w500,
|
||
color: textOnPrimary,
|
||
);
|
||
|
||
static TextStyle get labelMedium => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.w500,
|
||
color: textOnPrimary,
|
||
);
|
||
|
||
static TextStyle get labelSmall => const TextStyle(
|
||
fontFamily: fontFamily,
|
||
fontSize: 10,
|
||
fontWeight: FontWeight.w500,
|
||
color: textSecondary,
|
||
);
|
||
|
||
// 暗色主题颜色
|
||
static const Color darkBackgroundColor = Color(0xff121212);
|
||
static const Color darkSurfaceColor = Color(0xff1E1E1E);
|
||
static const Color darkTextPrimary = Color(0xffE0E0E0);
|
||
static const Color darkTextSecondary = Color(0xff9E9E9E);
|
||
static const Color darkDividerColor = Color(0xff373737);
|
||
static const Color darkBorderColor = Color(0xff424242);
|
||
|
||
// 主题数据
|
||
static ThemeData get lightTheme {
|
||
return ThemeData(
|
||
// 颜色
|
||
primaryColor: primaryColor,
|
||
primaryColorLight: primaryLight,
|
||
primaryColorDark: primaryDark,
|
||
colorScheme: const ColorScheme.light(
|
||
primary: primaryColor,
|
||
secondary: secondaryColor,
|
||
background: backgroundColor,
|
||
surface: surfaceColor,
|
||
error: errorColor,
|
||
onPrimary: textOnPrimary,
|
||
onSecondary: textOnSecondary,
|
||
),
|
||
|
||
// 字体
|
||
fontFamily: fontFamily,
|
||
|
||
// 文字主题
|
||
textTheme: TextTheme(
|
||
displayLarge: displayLarge,
|
||
displayMedium: displayMedium,
|
||
displaySmall: displaySmall,
|
||
headlineMedium: headlineMedium,
|
||
headlineSmall: headlineSmall,
|
||
titleLarge: titleLarge,
|
||
titleMedium: titleMedium,
|
||
titleSmall: titleSmall,
|
||
bodyLarge: bodyLarge,
|
||
bodyMedium: bodyMedium,
|
||
bodySmall: bodySmall,
|
||
labelLarge: labelLarge,
|
||
labelMedium: labelMedium,
|
||
labelSmall: labelSmall,
|
||
),
|
||
|
||
// 组件主题
|
||
appBarTheme: const AppBarTheme(
|
||
backgroundColor: surfaceColor,
|
||
foregroundColor: textPrimary,
|
||
elevation: 0,
|
||
centerTitle: true,
|
||
),
|
||
|
||
cardTheme: CardThemeData(
|
||
color: surfaceColor,
|
||
elevation: 2,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
margin: const EdgeInsets.all(spacingS),
|
||
),
|
||
|
||
buttonTheme: ButtonThemeData(
|
||
buttonColor: primaryColor,
|
||
textTheme: ButtonTextTheme.primary,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
),
|
||
|
||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: primaryColor,
|
||
foregroundColor: textOnPrimary,
|
||
padding: const EdgeInsets.symmetric(
|
||
horizontal: spacingL,
|
||
vertical: spacingM,
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
textStyle: labelLarge,
|
||
),
|
||
),
|
||
|
||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||
style: OutlinedButton.styleFrom(
|
||
side: const BorderSide(color: primaryColor),
|
||
padding: const EdgeInsets.symmetric(
|
||
horizontal: spacingL,
|
||
vertical: spacingM,
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
textStyle: labelLarge.copyWith(color: primaryColor),
|
||
),
|
||
),
|
||
|
||
inputDecorationTheme: InputDecorationTheme(
|
||
border: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: borderColor),
|
||
),
|
||
enabledBorder: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: borderColor),
|
||
),
|
||
focusedBorder: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: primaryColor),
|
||
),
|
||
filled: true,
|
||
fillColor: Colors.white,
|
||
contentPadding: const EdgeInsets.all(spacingM),
|
||
),
|
||
|
||
// 其他
|
||
useMaterial3: true,
|
||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||
);
|
||
}
|
||
|
||
// 暗色主题
|
||
static ThemeData get darkTheme {
|
||
return ThemeData(
|
||
// 颜色
|
||
primaryColor: primaryColor,
|
||
primaryColorLight: primaryLight,
|
||
primaryColorDark: primaryDark,
|
||
colorScheme: const ColorScheme.dark(
|
||
primary: primaryColor,
|
||
secondary: secondaryColor,
|
||
background: darkBackgroundColor,
|
||
surface: darkSurfaceColor,
|
||
error: errorColor,
|
||
onPrimary: textOnPrimary,
|
||
onSecondary: textOnSecondary,
|
||
),
|
||
|
||
// 字体
|
||
fontFamily: fontFamily,
|
||
|
||
// 文字主题
|
||
textTheme: TextTheme(
|
||
displayLarge: displayLarge.copyWith(color: darkTextPrimary),
|
||
displayMedium: displayMedium.copyWith(color: darkTextPrimary),
|
||
displaySmall: displaySmall.copyWith(color: darkTextPrimary),
|
||
headlineMedium: headlineMedium.copyWith(color: darkTextPrimary),
|
||
headlineSmall: headlineSmall.copyWith(color: darkTextPrimary),
|
||
titleLarge: titleLarge.copyWith(color: darkTextPrimary),
|
||
titleMedium: titleMedium.copyWith(color: darkTextPrimary),
|
||
titleSmall: titleSmall.copyWith(color: darkTextSecondary),
|
||
bodyLarge: bodyLarge.copyWith(color: darkTextPrimary),
|
||
bodyMedium: bodyMedium.copyWith(color: darkTextPrimary),
|
||
bodySmall: bodySmall.copyWith(color: darkTextSecondary),
|
||
labelLarge: labelLarge,
|
||
labelMedium: labelMedium,
|
||
labelSmall: labelSmall.copyWith(color: darkTextSecondary),
|
||
),
|
||
|
||
// 组件主题
|
||
appBarTheme: const AppBarTheme(
|
||
backgroundColor: darkSurfaceColor,
|
||
foregroundColor: darkTextPrimary,
|
||
elevation: 0,
|
||
centerTitle: true,
|
||
),
|
||
|
||
cardTheme: CardThemeData(
|
||
color: darkSurfaceColor,
|
||
elevation: 2,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
margin: const EdgeInsets.all(spacingS),
|
||
),
|
||
|
||
buttonTheme: ButtonThemeData(
|
||
buttonColor: primaryColor,
|
||
textTheme: ButtonTextTheme.primary,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
),
|
||
|
||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: primaryColor,
|
||
foregroundColor: textOnPrimary,
|
||
padding: const EdgeInsets.symmetric(
|
||
horizontal: spacingL,
|
||
vertical: spacingM,
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
textStyle: labelLarge,
|
||
),
|
||
),
|
||
|
||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||
style: OutlinedButton.styleFrom(
|
||
side: const BorderSide(color: primaryColor),
|
||
padding: const EdgeInsets.symmetric(
|
||
horizontal: spacingL,
|
||
vertical: spacingM,
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
),
|
||
textStyle: labelLarge.copyWith(color: primaryColor),
|
||
),
|
||
),
|
||
|
||
inputDecorationTheme: InputDecorationTheme(
|
||
border: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: darkBorderColor),
|
||
),
|
||
enabledBorder: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: darkBorderColor),
|
||
),
|
||
focusedBorder: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(borderRadiusM),
|
||
borderSide: const BorderSide(color: primaryColor),
|
||
),
|
||
filled: true,
|
||
fillColor: darkSurfaceColor,
|
||
contentPadding: const EdgeInsets.all(spacingM),
|
||
),
|
||
|
||
// 其他
|
||
useMaterial3: true,
|
||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||
brightness: Brightness.dark,
|
||
);
|
||
}
|
||
|
||
// 渐变
|
||
static LinearGradient get primaryGradient => LinearGradient(
|
||
colors: [primaryColor, primaryLight],
|
||
begin: Alignment.centerLeft,
|
||
end: Alignment.centerRight,
|
||
);
|
||
|
||
static LinearGradient get secondaryGradient => LinearGradient(
|
||
colors: [secondaryColor, secondaryLight],
|
||
begin: Alignment.centerLeft,
|
||
end: Alignment.centerRight,
|
||
);
|
||
|
||
static LinearGradient get successGradient => LinearGradient(
|
||
colors: [successColor, Color(0xff66BB6A)],
|
||
begin: Alignment.centerLeft,
|
||
end: Alignment.centerRight,
|
||
);
|
||
} |