使用主题共享颜色和字体样式
要在一个应用中共享颜色和字体样式,请使用主题。
您可以定义应用范围的主题。 您可以扩展主题以更改一个组件的主题样式。 每个主题都定义了适用于 Material 组件类型的颜色、类型样式和其他参数。
Flutter 按以下顺序应用样式:
- 应用于特定小部件的样式。
- 覆盖直接父主题的主题。
- 整个应用的主主题。
定义 Theme
后,在您自己的小部件中使用它。Flutter 的 Material 小部件使用您的主题来设置应用栏、按钮、复选框等的背景颜色和字体样式。
创建应用主题
#要在整个应用中共享 Theme
,请将 theme
属性设置为 MaterialApp
构造函数。此属性采用 ThemeData
实例。
从 Flutter 3.16 版本开始,Material 3 是 Flutter 的默认主题。
如果在构造函数中未指定主题,Flutter 会为您创建一个默认主题。
MaterialApp(
title: appName,
theme: ThemeData(
useMaterial3: true,
// 定义默认亮度和颜色。
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.purple,
// ···
brightness: Brightness.dark,
),
// 定义默认 `TextTheme`。使用此项指定标题、标题、正文等默认文本样式。
textTheme: TextTheme(
displayLarge: const TextStyle(
fontSize: 72,
fontWeight: FontWeight.bold,
),
// ···
titleLarge: GoogleFonts.oswald(
fontSize: 30,
fontStyle: FontStyle.italic,
),
bodyMedium: GoogleFonts.merriweather(),
displaySmall: GoogleFonts.pacifico(),
),
),
home: const MyHomePage(
title: appName,
),
);
大多数 ThemeData
实例都为以下两个属性设置值。这两个属性会影响整个应用。
colorScheme
定义颜色。textTheme
定义文本样式。
要了解您可以定义的颜色、字体和其他属性,请查看 ThemeData
文档。
应用主题
#要应用新的主题,请在指定小部件的样式属性时使用 Theme.of(context)
方法。这些属性可以包括但不限于 style
和 color
。
Theme.of(context)
方法查找小部件树并检索树中最接近的 Theme
。如果您有一个独立的 Theme
,则会应用该主题。如果没有,Flutter 会应用应用的主题。
在以下示例中,Container
构造函数使用此技术来设置其 color
。
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
color: Theme.of(context).colorScheme.primary,
child: Text(
'带有背景颜色的文本',
// ···
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onPrimary,
),
),
),
覆盖主题
#要在应用的一部分中覆盖整体主题,请将应用的该部分包装在 Theme
小部件中。
您可以通过两种方式覆盖主题:
- 创建一个唯一的
ThemeData
实例。 - 扩展父主题。
设置唯一的 ThemeData
实例
#如果希望应用的某个组件忽略整体主题,请创建一个 ThemeData
实例。将该实例传递给 Theme
小部件。
Theme(
// 使用 `ThemeData` 创建一个唯一的主题。
data: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.pink,
),
),
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
扩展父主题
#与其覆盖所有内容,不如考虑扩展父主题。要扩展主题,请使用 copyWith()
方法。
Theme(
// 使用 `copyWith` 查找并扩展父主题。要了解更多信息,请查看有关 `Theme.of` 的部分。
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.pink,
),
),
child: const FloatingActionButton(
onPressed: null,
child: Icon(Icons.add),
),
);
观看关于 Theme
的视频
#要了解更多信息,请观看此关于 Theme
小部件的简短“每周小部件”视频:
Theme | Flutter widget of the week
尝试交互式示例
#import 'package:flutter/material.dart';
// 包含 Google Fonts 包以提供更多文本格式选项
// https://pub.dev/packages/google_fonts
import 'package:google_fonts/google_fonts.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const appName = '自定义主题';
return MaterialApp(
title: appName,
theme: ThemeData(
useMaterial3: true,
// 定义默认亮度和颜色。
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.purple,
// 试试这个:更改为 "Brightness.light"
// 然后你会看到所有颜色都改变了
// 以更好地与浅色背景形成对比。
brightness: Brightness.dark,
),
// 定义默认 `TextTheme`。使用此项指定标题、标题、正文等默认文本样式。
textTheme: TextTheme(
displayLarge: const TextStyle(
fontSize: 72,
fontWeight: FontWeight.bold,
),
// 试试这个:将其中一个 GoogleFonts
// 更改为 "lato"、"poppins" 或 "lora"。
// 标题使用 "titleLarge"
// 中间文本使用 "bodyMedium"。
titleLarge: GoogleFonts.oswald(
fontSize: 30,
fontStyle: FontStyle.italic,
),
bodyMedium: GoogleFonts.merriweather(),
displaySmall: GoogleFonts.pacifico(),
),
),
home: const MyHomePage(
title: appName,
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
const MyHomePage({super.key, required this.title});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title,
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Theme.of(context).colorScheme.onSecondary,
)),
backgroundColor: Theme.of(context).colorScheme.secondary,
),
body: Center(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
color: Theme.of(context).colorScheme.primary,
child: Text(
'带有背景颜色的文本',
// 试试这个:更改文本值
// 或将 Theme.of(context).textTheme
// 更改为 "displayLarge" 或 "displaySmall"。
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onPrimary,
),
),
),
),
floatingActionButton: Theme(
data: Theme.of(context).copyWith(
// 试试这个:将 seedColor 更改为 "Colors.red" 或
// "Colors.blue"。
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.pink,
brightness: Brightness.dark,
),
),
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
),
);
}
}
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。