Flutter样式与主题 #
一、ThemeData #
1.1 基本用法 #
ThemeData定义了应用的主题配置。
dart
ThemeData({
bool? applyElevationOverlayColor,
NoDefaultCupertinoThemeData? cupertinoOverrideTheme,
Iterable<ThemeExtension>? extensions,
InputDecorationTheme? inputDecorationTheme,
MaterialTapTargetSize? materialTapTargetSize,
PageTransitionsTheme? pageTransitionsTheme,
TargetPlatform? platform,
ScrollBehavior? scrollBehavior,
TapDownDetails? tapDownDetails,
ColorScheme? colorScheme,
Brightness? brightness,
Color? primaryColor,
Color? primaryColorLight,
Color? primaryColorDark,
Color? canvasColor,
Color? cardColor,
Color? dividerColor,
Color? highlightColor,
Color? splashColor,
InteractiveInkFeatureFactory? splashFactory,
Color? hoverColor,
Color? focusColor,
Color? scaffoldBackgroundColor,
Color? bottomAppBarColor,
Color? dialogBackgroundColor,
Color? indicatorColor,
Color? hintColor,
Color? errorColor,
Color? toggleableActiveColor,
TextTheme? textTheme,
TextTheme? primaryTextTheme,
IconThemeData? iconTheme,
IconThemeData? primaryIconTheme,
AppBarTheme? appBarTheme,
ButtonThemeData? buttonTheme,
CardTheme? cardTheme,
ChipThemeData? chipTheme,
ElevatedButtonThemeData? elevatedButtonTheme,
FilledButtonThemeData? filledButtonTheme,
OutlinedButtonThemeData? outlinedButtonTheme,
TextButtonThemeData? textButtonTheme,
FloatingActionButtonThemeData? floatingActionButtonTheme,
IconButtonThemeData? iconButtonTheme,
DialogTheme? dialogTheme,
DividerThemeData? dividerTheme,
ListTileThemeData? listTileTheme,
NavigationBarThemeData? navigationBarTheme,
NavigationRailThemeData? navigationRailTheme,
TabBarTheme? tabBarTheme,
DrawerThemeData? drawerTheme,
SnackBarThemeData? snackBarTheme,
BottomSheetThemeData? bottomSheetTheme,
CheckboxThemeData? checkboxTheme,
RadioThemeData? radioTheme,
SwitchThemeData? switchTheme,
ProgressIndicatorThemeData? progressIndicatorTheme,
SliderThemeData? sliderTheme,
TimePickerThemeData? timePickerTheme,
DatePickerThemeData? datePickerTheme,
DataTableThemeData? dataTableTheme,
PopupMenuThemeData? popupMenuTheme,
TooltipThemeData? tooltipTheme,
BottomNavigationBarThemeData? bottomNavigationBarTheme,
BottomAppBarTheme? bottomAppBarTheme,
MenuBarThemeData? menuBarTheme,
MenuStyle? menuButtonTheme,
DropdownMenuThemeData? dropdownMenuTheme,
SearchBarThemeData? searchBarTheme,
SearchViewThemeData? searchViewTheme,
})
1.2 常用配置 #
dart
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
brightness: Brightness.light,
primaryColor: Colors.blue,
scaffoldBackgroundColor: Colors.white,
appBarTheme: AppBarTheme(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
cardTheme: CardTheme(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
filled: true,
fillColor: Colors.grey.shade100,
),
),
)
二、ColorScheme #
2.1 从种子颜色生成 #
dart
ColorScheme.fromSeed({
required Color seedColor,
Brightness brightness = Brightness.light,
Color? primary,
Color? onPrimary,
Color? primaryContainer,
Color? onPrimaryContainer,
Color? secondary,
Color? onSecondary,
Color? secondaryContainer,
Color? onSecondaryContainer,
Color? tertiary,
Color? onTertiary,
Color? tertiaryContainer,
Color? onTertiaryContainer,
Color? error,
Color? onError,
Color? errorContainer,
Color? onErrorContainer,
Color? surface,
Color? onSurface,
Color? surfaceContainerHighest,
Color? onSurfaceVariant,
Color? outline,
Color? outlineVariant,
Color? shadow,
Color? scrim,
Color? inverseSurface,
Color? onInverseSurface,
Color? inversePrimary,
Color? surfaceTint,
})
ColorScheme.fromSeed(seedColor: Colors.blue)
ColorScheme.fromSeed(seedColor: Colors.blue, brightness: Brightness.dark)
2.2 颜色角色 #
dart
ThemeData(
colorScheme: ColorScheme(
brightness: Brightness.light,
primary: Colors.blue,
onPrimary: Colors.white,
primaryContainer: Colors.blue.shade100,
onPrimaryContainer: Colors.blue.shade900,
secondary: Colors.teal,
onSecondary: Colors.white,
secondaryContainer: Colors.teal.shade100,
onSecondaryContainer: Colors.teal.shade900,
tertiary: Colors.orange,
onTertiary: Colors.white,
error: Colors.red,
onError: Colors.white,
surface: Colors.white,
onSurface: Colors.black,
),
)
2.3 使用颜色 #
dart
Container(
color: Theme.of(context).colorScheme.primary,
)
Container(
color: Theme.of(context).colorScheme.secondary,
)
Container(
color: Theme.of(context).colorScheme.error,
)
三、TextTheme #
3.1 文本样式 #
dart
ThemeData(
textTheme: TextTheme(
displayLarge: TextStyle(fontSize: 57, fontWeight: FontWeight.w400),
displayMedium: TextStyle(fontSize: 45, fontWeight: FontWeight.w400),
displaySmall: TextStyle(fontSize: 36, fontWeight: FontWeight.w400),
headlineLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.w400),
headlineMedium: TextStyle(fontSize: 28, fontWeight: FontWeight.w400),
headlineSmall: TextStyle(fontSize: 24, fontWeight: FontWeight.w400),
titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.w400),
titleMedium: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
titleSmall: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
bodyLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
bodyMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
bodySmall: TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
labelLarge: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
labelMedium: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
labelSmall: TextStyle(fontSize: 11, fontWeight: FontWeight.w500),
),
)
3.2 使用文本样式 #
dart
Text(
'Title',
style: Theme.of(context).textTheme.titleLarge,
)
Text(
'Body text',
style: Theme.of(context).textTheme.bodyMedium,
)
四、暗黑模式 #
4.1 配置暗黑主题 #
dart
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.light,
),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
useMaterial3: true,
),
themeMode: ThemeMode.system,
)
4.2 ThemeMode #
dart
ThemeMode.system
ThemeMode.light
ThemeMode.dark
4.3 动态切换主题 #
dart
class ThemeProvider extends ChangeNotifier {
ThemeMode _themeMode = ThemeMode.system;
ThemeMode get themeMode => _themeMode;
void setThemeMode(ThemeMode mode) {
_themeMode = mode;
notifyListeners();
}
void toggleTheme() {
_themeMode = _themeMode == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light;
notifyListeners();
}
}
MaterialApp(
themeMode: context.watch<ThemeProvider>().themeMode,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
)
五、Theme Widget #
5.1 局部主题 #
dart
Theme(
data: Theme.of(context).copyWith(
primaryColor: Colors.red,
),
child: Builder(
builder: (context) {
return Container(
color: Theme.of(context).primaryColor,
);
},
),
)
5.2 获取主题 #
dart
final theme = Theme.of(context);
final colorScheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme;
六、自定义主题扩展 #
6.1 ThemeExtension #
dart
class MyColors extends ThemeExtension<MyColors> {
final Color? brand;
final Color? accent;
MyColors({
required this.brand,
required this.accent,
});
@override
MyColors copyWith({
Color? brand,
Color? accent,
}) {
return MyColors(
brand: brand ?? this.brand,
accent: accent ?? this.accent,
);
}
@override
MyColors lerp(MyColors? other, double t) {
if (other is! MyColors) {
return this;
}
return MyColors(
brand: Color.lerp(brand, other.brand, t),
accent: Color.lerp(accent, other.accent, t),
);
}
}
ThemeData(
extensions: [
MyColors(
brand: Colors.purple,
accent: Colors.orange,
),
],
)
final myColors = Theme.of(context).extension<MyColors>()!;
七、总结 #
7.1 核心概念 #
| 概念 | 说明 |
|---|---|
| ThemeData | 主题配置 |
| ColorScheme | 颜色方案 |
| TextTheme | 文本样式 |
| ThemeMode | 主题模式 |
7.2 下一步 #
掌握了样式与主题后,让我们学习 状态管理概述!
最后更新:2026-03-28