是什么
ColorScheme
是 Flutter(特别是 Material 3)主题系统的核心类,用来统一管理 App 的所有语义化颜色。它不是单纯的颜色集合,而是 带有角色意义的颜色系统,每个属性代表 UI 中一个特定的语义场景。这样Flutter 的内置组件(如 AppBar
、Button
、Card
等)就能根据语义自动使用合适的颜色。
一个 ColorScheme
大致分为以下几类:
- 主色(Primary / Secondary / Tertiary)系列 → 用于突出品牌、强调内容。
- 错误色(Error)系列 → 用于错误提示、警告。
- 表面(Surface)系列 → 各种容器、背景。
- 文字与图标(OnXxx)系列 → 表示在某种背景色上的前景色。
- 辅助属性(outline / shadow / scrim / inverse 等) → 用于边框、遮罩、反转场景。
- Fixed & Container 扩展色(Material 3 引入)→ 提供更多层级的颜色,用于不同层次的 UI。
属性
常见属性
属性 | 作用 | 常见使用场景 |
---|---|---|
brightness | 明暗模式(light / dark),决定整体基调 | Material 自动适配文本/图标对比度 |
primary | 主色,品牌色、重点按钮颜色 | AppBar 、FAB 、Button |
onPrimary | 主色上的前景色 | 主色按钮的文字、图标 |
primaryContainer | 主色容器色,主色的扩展背景 | Card 、选中状态背景 |
onPrimaryContainer | 主色容器上的前景色 | 容器里的文字、图标 |
secondary | 次要色,辅助强调 | Chip 、辅助按钮 |
onSecondary | 次要色上的前景色 | 次要按钮的文字 |
secondaryContainer | 次要容器色 | 卡片背景、分组背景 |
onSecondaryContainer | 次要容器前景色 | 次要容器里的文字 |
tertiary | 第三强调色,用于特殊功能 | 装饰性元素、图表高亮 |
onTertiary | 第三强调色上的前景色 | 第三色上的文字 |
tertiaryContainer | 第三色容器 | 对话框、底部抽屉 |
onTertiaryContainer | 第三色容器上的前景色 | 文字、图标 |
error | 错误色 | 表单错误、警告提示 |
onError | 错误背景上的前景色 | 错误按钮文字 |
errorContainer | 错误容器背景 | 错误提示卡片 |
onErrorContainer | 错误容器上的前景色 | 错误描述文字 |
surface | 表面色,UI 背景主色 | Scaffold 背景、卡片 |
onSurface | 表面上的前景色 | 页面文字、图标 |
onSurfaceVariant | 表面变体上的前景色 | 次级文字、禁用文字 |
surfaceTint | 表面着色(M3 新特性) | 卡片高亮、层次感 |
outline | 轮廓色 | 边框、分割线 |
outlineVariant | 边框弱化色 | 次级边框、禁用边框 |
shadow | 阴影颜色 | 卡片、浮动按钮投影 |
scrim | 遮罩颜色 | 弹窗、模态背景 |
inverseSurface | 反转表面色 | 夜间模式 / 对比背景 |
inversePrimary | 反转主色 | 深色模式下的主色替代 |
Material 3 扩展属性
属性 | 作用 | 常见使用场景 |
---|---|---|
primaryFixed / primaryFixedDim | 固定的主色(不随明暗变化) | 固定强调区域 |
onPrimaryFixed / onPrimaryFixedVariant | 固定主色上的前景色 | 文字、图标 |
secondaryFixed / secondaryFixedDim | 固定的次色 | 辅助区域 |
tertiaryFixed / tertiaryFixedDim | 固定的第三色 | 装饰区域 |
surfaceDim / surfaceBright | 表面不同亮度层级 | 暗背景 / 亮背景 |
surfaceContainerLowest → Highest | 多层次容器背景 | 多层卡片、分区背景 |
brightness
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isDark = false;
@override
Widget build(BuildContext context) {
return 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: _isDark ? ThemeMode.dark : ThemeMode.light,
home: Scaffold(
appBar: AppBar(title: const Text("ColorScheme.brightness 示例")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("Hello Brightness!", style: TextStyle(fontSize: 32)),
const SizedBox(height: 20),
Text(
_isDark ? "当前:Dark 模式" : "当前:Light 模式",
style: const TextStyle(fontSize: 20),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => _isDark = !_isDark),
child: const Icon(Icons.brightness_6),
),
),
);
}
}
在 ThemeData
里的 brightness
这是 Flutter 较早的写法,在 Material 2 时代主要靠它区分浅色/深色主题。
它本质上是一个 快捷方式,影响整个 ThemeData
的默认颜色。
但是,它的颗粒度比较粗:
- 设置
Brightness.dark
就会自动应用一组「暗色」的默认颜色(比如背景黑、文字白)。 - 你不能对每个角色(如
primary
、onBackground
、surface
)分别定制。
在 ColorScheme
里的 brightness
从 Material 3 开始,官方推荐用 ColorScheme
作为唯一颜色来源。
ColorScheme
更精细,包含了完整的色彩体系(primary、secondary、background、surface、error 等等)。
brightness
在 ColorScheme
里起到 基调作用:
Brightness.light
→primary
、background
等都会自动生成浅色系。Brightness.dark
→ 同一套色板会生成深色版本。
这样,主题的所有组件(按钮、卡片、文字、背景)都从同一个 ColorScheme
派生,风格统一。
两者区别
属性 | 时代/背景 | 控制范围 | 灵活性 | 推荐使用场景 |
---|---|---|---|---|
ThemeData.brightness | Material 2 遗留写法 | 整个主题整体的明暗 | 粗粒度,不能细调 | 老项目、快速区分亮/暗 |
ColorScheme.brightness | Material 3 推荐方案 | 影响整个 ColorScheme 的生成 |
精细、全局一致 | 新项目,需完整配色系统 |
创建 ColorScheme
的方式
创建方式 | 用法 | 适合场景 | 是否推荐 |
---|---|---|---|
ColorScheme.fromSeed |
自动生成整套配色 | 你只提供一个种子颜色(如蓝色),其余自动生成 | ✅ 最推荐(Material 3 风格) |
ColorScheme.light() |
创建一套浅色主题的默认颜色 | 想快速得到一套浅色默认颜色 | ✅ 常用 |
ColorScheme.dark() |
创建一套深色主题的默认颜色 | 想快速得到一套深色默认颜色 | ✅ 常用 |
ColorScheme(...) 构造函数(手动指定) |
自己定义每一个颜色 | 完全自定义配色 | ✅ 高级用法(定制主题) |
ColorScheme.fromSeed
final colorScheme = ColorScheme.fromSeed(
seedColor: Colors.teal,
brightness: Brightness.light,
);
只传一个
seedColor
,它会帮你自动生成整套颜色。如何理解「成套的颜色」
在 Material Design 3 里,一个主题不是单一的颜色,而是一整套互相关联的颜色(
primary
、secondary
、tertiary
、surface
、error
等)。如果你只传一个
seedColor
,Flutter 会基于这个颜色 自动生成一套和谐的色板,确保按钮、背景、文本等颜色搭配合理。就像你给设计师说:“主色是蓝色”,设计师就会自动帮你配好次要色、容器色、对比色。
默认遵循 Material 3 动态色彩规范。
也可以加上
brightness: Brightness.dark
来生成深色版本。
**优点:**①一致性强;②自动生成搭配良好的配色;③支持浅色/深色两套
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(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), // 只传蓝色
useMaterial3: true,
),
home: const ColorSchemeDemo(),
);
}
}
class ColorSchemeDemo extends StatelessWidget {
const ColorSchemeDemo({super.key});
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(title: const Text("ColorScheme.fromSeed 示例")),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
height: 60,
width: double.infinity,
color: scheme.primary,
child: Center(
child: Text(
"Primary",
style: TextStyle(color: scheme.onPrimary),
),
),
),
const SizedBox(height: 10),
Container(
height: 60,
width: double.infinity,
color: scheme.secondary,
child: Center(
child: Text(
"Secondary",
style: TextStyle(color: scheme.onSecondary),
),
),
),
const SizedBox(height: 10),
Container(
height: 60,
width: double.infinity,
color: scheme.tertiary,
child: Center(
child: Text(
"Tertiary",
style: TextStyle(color: scheme.onTertiary),
),
),
),
const SizedBox(height: 10),
Container(
height: 60,
width: double.infinity,
color: scheme.error,
child: Center(
child: Text("Error", style: TextStyle(color: scheme.onError)),
),
),
],
),
),
);
}
}
效果说明
- 我们只传了
Colors.blue
,但是 Flutter 自动生成了:primary
蓝色secondary
比较柔和的蓝紫色tertiary
辅助的对比色error
红色(系统内置的警示色)surface
、background
等浅色搭配
- 整个 UI 的 对比色(onPrimary、onSecondary)也自动生成,保证文字在背景上可见。

ColorScheme.light / ColorScheme.dark
final lightScheme = ColorScheme.light();
final darkScheme = ColorScheme.dark();
这是 Flutter 提供的默认浅色 / 深色配色方案。
可以传参数来自定义某些颜色:
final customLight = ColorScheme.light(
primary: Colors.deepPurple,
secondary: Colors.orange,
);
优点:
- 快速得到一套配色
- 适合不使用 Material 3 动态色的情况
ColorScheme(…) 构造函数
final customScheme = const ColorScheme(
brightness: Brightness.light,
primary: Color(0xff00214a),
onPrimary: Colors.white,
secondary: Color(0xff192232),
onSecondary: Colors.white,
error: Color(0xffb00020),
onError: Colors.white,
background: Color(0xfff9f9ff),
onBackground: Colors.black,
surface: Colors.white,
onSurface: Colors.black,
// 还要继续写所有必填字段……
);
特点:
- 所有字段都要你自己填,没填会报错
- 用于完全掌控配色方案
- 一般用于企业设计系统、自定义主题