gcx/frontend/mobile/lib/app/theme/app_theme.dart

231 lines
8.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'app_colors.dart';
import 'app_typography.dart';
import 'app_spacing.dart';
/// Genex Material 3 Theme Configuration
///
/// 干净清爽型紫色主题零区块链感知的金融App体验
class AppTheme {
AppTheme._();
static ThemeData get light => ThemeData(
useMaterial3: true,
brightness: Brightness.light,
// Color Scheme
colorScheme: const ColorScheme.light(
primary: AppColors.primary,
primaryContainer: AppColors.primaryContainer,
secondary: AppColors.success,
secondaryContainer: AppColors.successLight,
tertiary: AppColors.info,
error: AppColors.error,
errorContainer: AppColors.errorLight,
surface: AppColors.surface,
surfaceContainerHighest: AppColors.surfaceVariant,
onPrimary: Colors.white,
onSecondary: Colors.white,
onSurface: AppColors.textPrimary,
onSurfaceVariant: AppColors.textSecondary,
outline: AppColors.border,
outlineVariant: AppColors.borderLight,
scrim: AppColors.scrim,
),
scaffoldBackgroundColor: AppColors.background,
// AppBar
appBarTheme: const AppBarTheme(
elevation: 0,
scrolledUnderElevation: 0.5,
centerTitle: true,
backgroundColor: AppColors.surface,
foregroundColor: AppColors.textPrimary,
surfaceTintColor: Colors.transparent,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
),
titleTextStyle: AppTypography.h3,
iconTheme: IconThemeData(color: AppColors.textPrimary, size: 24),
),
// Bottom Navigation
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed,
backgroundColor: AppColors.surface,
selectedItemColor: AppColors.primary,
unselectedItemColor: AppColors.textTertiary,
elevation: 0,
selectedLabelStyle: TextStyle(fontSize: 11, fontWeight: FontWeight.w600),
unselectedLabelStyle: TextStyle(fontSize: 11, fontWeight: FontWeight.w400),
),
// Navigation Bar (M3)
navigationBarTheme: NavigationBarThemeData(
backgroundColor: AppColors.surface,
indicatorColor: AppColors.primaryContainer,
surfaceTintColor: Colors.transparent,
elevation: 0,
height: AppSpacing.bottomNavHeight,
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
iconTheme: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return const IconThemeData(color: AppColors.primary, size: 24);
}
return const IconThemeData(color: AppColors.textTertiary, size: 24);
}),
labelTextStyle: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppTypography.caption.copyWith(
color: AppColors.primary,
fontWeight: FontWeight.w600,
);
}
return AppTypography.caption;
}),
),
// Card
cardTheme: CardThemeData(
elevation: 0,
color: AppColors.surface,
surfaceTintColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusMd,
side: const BorderSide(color: AppColors.borderLight, width: 1),
),
margin: EdgeInsets.zero,
),
// Elevated Button
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
foregroundColor: Colors.white,
elevation: 0,
minimumSize: const Size(0, AppSpacing.buttonHeight),
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusMd,
),
textStyle: AppTypography.labelLarge,
),
),
// Outlined Button
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
foregroundColor: AppColors.primary,
side: const BorderSide(color: AppColors.primary, width: 1.5),
minimumSize: const Size(0, AppSpacing.buttonHeight),
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusMd,
),
textStyle: AppTypography.labelLarge,
),
),
// Text Button
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: AppColors.primary,
textStyle: AppTypography.labelMedium,
),
),
// Input Decoration
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: AppColors.gray50,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
border: OutlineInputBorder(
borderRadius: AppSpacing.borderRadiusMd,
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: AppSpacing.borderRadiusMd,
borderSide: const BorderSide(color: AppColors.borderLight, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: AppSpacing.borderRadiusMd,
borderSide: const BorderSide(color: AppColors.primary, width: 1.5),
),
errorBorder: OutlineInputBorder(
borderRadius: AppSpacing.borderRadiusMd,
borderSide: const BorderSide(color: AppColors.error, width: 1),
),
hintStyle: AppTypography.bodyMedium.copyWith(color: AppColors.textTertiary),
labelStyle: AppTypography.bodyMedium,
errorStyle: AppTypography.caption.copyWith(color: AppColors.error),
),
// Chip
chipTheme: ChipThemeData(
backgroundColor: AppColors.gray50,
selectedColor: AppColors.primaryContainer,
labelStyle: AppTypography.labelSmall,
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusFull,
),
side: const BorderSide(color: AppColors.borderLight),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
),
// TabBar
tabBarTheme: TabBarThemeData(
labelColor: AppColors.primary,
unselectedLabelColor: AppColors.textTertiary,
labelStyle: AppTypography.labelMedium,
unselectedLabelStyle: AppTypography.labelMedium,
indicatorSize: TabBarIndicatorSize.label,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(color: AppColors.primary, width: 2.5),
),
dividerColor: Colors.transparent,
),
// Dialog
dialogTheme: DialogThemeData(
backgroundColor: AppColors.surface,
surfaceTintColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusLg,
),
titleTextStyle: AppTypography.h2,
contentTextStyle: AppTypography.bodyMedium,
),
// BottomSheet
bottomSheetTheme: const BottomSheetThemeData(
backgroundColor: AppColors.surface,
surfaceTintColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
showDragHandle: true,
dragHandleColor: AppColors.gray300,
dragHandleSize: Size(36, 4),
),
// Divider
dividerTheme: const DividerThemeData(
color: AppColors.borderLight,
thickness: 1,
space: 0,
),
// Snackbar
snackBarTheme: SnackBarThemeData(
backgroundColor: AppColors.gray800,
contentTextStyle: AppTypography.bodyMedium.copyWith(color: Colors.white),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: AppSpacing.borderRadiusMd,
),
),
);
}