在 Flutter 3.35.2 中设置 APP 的主题颜色主要通过配置 ThemeData
来实现,这允许你统一管理应用的整体视觉风格。
🎨 Flutter 3.35.2 主题颜色设置指南
基本主题设置方法
在 Flutter 中,你通常是在应用的根 MaterialApp
或 CupertinoApp
widget 中通过 theme
属性来定义全局主题的。
全局主题设置
以下是在 MaterialApp
中全局设置主题颜色的基本代码结构:
dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '我的应用',
theme: ThemeData(
useMaterial3: true, // 使用 Material 3 设计
primaryColor: Colors.blue, // 主要颜色,用于导航栏、按钮等
primaryColorDark: Colors.blue[800], // 主要颜色的深色变体
primaryColorLight: Colors.blue[100], // 主要颜色的浅色变体
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), // 基于种子颜色生成配色方案
scaffoldBackgroundColor: Colors.grey[50], // 页面背景色
appBarTheme: const AppBarTheme(
backgroundColor: Colors.blue, // AppBar 背景色
foregroundColor: Colors.white, // AppBar 上的文字和图标颜色
),
textTheme: const TextTheme(
bodyMedium: TextStyle(color: Colors.black87), // 默认文本颜色
),
),
home: const MyHomePage(),
);
}
}

常用主题颜色属性说明
下表列出了 ThemeData
中一些常用的颜色属性及其用途:
属性 | 描述 | 示例值 |
---|---|---|
primaryColor |
应用的主要品牌颜色,用于导航栏、按钮等关键元素。 | Colors.blue |
primaryColorDark |
primaryColor 的深色变体,适用于需要更高对比度的场合。 |
Colors.blue[800] |
primaryColorLight |
primaryColor 的浅色变体。 |
Colors.blue[100] |
colorScheme |
定义一组基于 Material 2 或 Material 3 的颜色角色,推荐使用 fromSeed 方法。 |
ColorScheme.fromSeed(seedColor: Colors.blue) |
scaffoldBackgroundColor |
作为 Scaffold 组件默认背景色,即页面的背景颜色。 |
Colors.grey[50] |
appBarTheme |
用于定义应用栏(AppBar)的样式,包括颜色、文字样式等。 | AppBarTheme(color: Colors.blue) |
textTheme |
定义应用中文本的样式,如字体、颜色、大小等。 | TextTheme(bodyMedium: TextStyle(color: Colors.black87)) |
accentColor (已弃用) |
旧版的前景色(按钮、文本、覆盖边缘效果等),建议改用 colorScheme 的 secondary 。 |
Colors.green |
hintColor |
用于提示文本或占位符文本的颜色,例如在 TextField 中。 |
Colors.grey |
errorColor |
用于输入验证错误等场景的颜色。 | Colors.red |
使用 primarySwatch
创建材质调色板
primarySwatch
是 Material Design 中的一个概念,它接受一个 MaterialColor
对象,该对象包含一种颜色的 10 种不同深浅变体。Flutter 提供了一些预定义的材质颜色。
dart
ThemeData(
primarySwatch: Colors.blue, // 使用预定义的蓝色调色板
),
请注意 :primarySwatch
和 primaryColor
是互斥的。如果同时设置了两者,primaryColor
会覆盖 primarySwatch
中的主色。Flutter 预定义的材质颜色是有限的(如 Colors.blue、Colors.red 等)。如果你的品牌色不在其中,你需要自定义 MaterialColor
。
如何自定义 MaterialColor
如果你的主题色不是 Flutter 预定义的那些材质颜色,你可以通过定义 MaterialColor
来创建自己的调色板。
dart
// 自定义一个 MaterialColor(例如,主色为 0xFF913f91)
const MaterialColor myCustomPurple = MaterialColor(
0xFF913f91, // 主要颜色的 ARGB 值
<int, Color>{
50: Color(0xFFf3e5f5),
100: Color(0xFFe1bee7),
200: Color(0xFFce93d8),
300: Color(0xFFba68c8),
400: Color(0xFFab47bc),
500: Color(0xFF9c27b0), // 主要色调
600: Color(0xFF8e24aa),
700: Color(0xFF7b1fa2),
800: Color(0xFF6a1b9a),
900: Color(0xFF4a148c),
},
);
// 在 ThemeData 中使用
ThemeData(
primarySwatch: myCustomPurple,
);
使用 ColorScheme
(推荐)
从 Flutter 3.16 开始,Material 3 成为默认主题。使用 ColorScheme
(特别是 ColorScheme.fromSeed
)是更现代和灵活的方式,它能基于一种种子颜色生成一套协调的配色方案。
dart
ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue, // 你的品牌色
brightness: Brightness.light, // 亮度模式(light 或 dark)
),
useMaterial3: true, // 启用 Material 3
);

在 Widget 中使用主题色
定义好主题后,你可以在应用的任何 widget 中通过 Theme.of(context)
来获取并使用这些颜色:
dart
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
title: Text('首页', style: TextStyle(color: Theme.of(context).primaryColor)),
),
body: Container(
color: Theme.of(context).colorScheme.primaryContainer, // 使用 ColorScheme 中的颜色
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Theme.of(context).colorScheme.primary, // 使用主色
foregroundColor: Theme.of(context).colorScheme.onPrimary, // 使用主色上的文本/图标色
child: const Icon(Icons.add),
),
);
}
局部主题覆盖
若想在某些特定部分使用不同的主题,可以使用 Theme
widget 来覆盖父级主题。
dart
Theme(
// 完全覆盖一个新的 ThemeData
data: ThemeData.dark().copyWith(primaryColor: Colors.pink),
// 或者继承当前主题并只覆盖特定属性
// data: Theme.of(context).copyWith(primaryColor: Colors.pink),
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
暗色主题
支持暗色主题可以提升用户体验。你可以通过定义 darkTheme
属性并配合 themeMode
来实现。
dart
MaterialApp(
theme: ThemeData.light().copyWith( // 亮色主题
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue, brightness: Brightness.light),
),
darkTheme: ThemeData.dark().copyWith( // 暗色主题
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue, brightness: Brightness.dark),
),
themeMode: ThemeMode.system, // 跟随系统、亮色或暗色
home: const MyHomePage(),
);
实用技巧与注意事项
primarySwatch
与primaryColor
:理解它们的区别很重要。primarySwatch
提供一系列颜色 shades,而primaryColor
通常只设置单一主色。若同时设置,primaryColor
会覆盖primarySwatch
的主色。- 亮度 (
brightness
) :Brightness.light
和Brightness.dark
决定了主题的整体亮度,这会影响系统状态栏图标颜色(亮或暗)以及一些默认 widget 的外观。 - 使用
copyWith
方法 :当你想在现有主题基础上只修改少数几个属性时,ThemeData.copyWith()
方法非常有用,可以避免重新定义所有属性。 - 在代码中引用主题色 :尽量使用
Theme.of(context).colorScheme.primary
而不是直接使用Colors.blue
这样的硬编码颜色值,这样能保证主题切换时颜色自动更新。 - 自定义颜色 :对于品牌色,自定义
MaterialColor
可以让你在不同状态下都有合适的颜色深浅可用。 - 测试对比度:确保文本和图标在其背景色上有足够的对比度,以保证可访问性。