ColorPicker
ColorPicker 是一个高度可配置的 Flutter 颜色选择器。ColorPicker 可以显示 1 到 6 种不同的颜色选择工具,您可以使用它们来选择颜色。

不同的颜色选择选项包括:
- Material 原始颜色及其色调。
ColorPickerSwatch.material - Material 强调色及其色调。
ColorPickerSwatch.accent - Material 原始颜色和强调色及其色调,在同一个颜色选择器中。
ColorPickerSwatch.both - 黑色和白色,包括近黑和近白色调。
ColorPickerSwatch.bw - 自定义的 Material 风格颜色及其色调,由您定义和命名。
ColorPickerSwatch.custom - 一个 HSV 色轮选择器,允许您选择任何颜色。所选颜色的 Material 原始颜色色调会自动计算。
ColorPickerSwatch.any
当您显示一种以上的颜色样本选择工具时,一个滑块允许您选择要使用的工具。您可以配置颜色选择器以包含以上任何颜色样本。显示选项 1 和 2,以及选项 3 并不十分有用,它们可以作为显示 Material 原始颜色和强调颜色的可选方式。
您可以为选择器提供标题和副标题,通常是具有适当样式的 Text 小部件。您还可以定义 Material 色调是否可以选择,以及所选颜色的名称和值是否在选择器中显示。如果显示了值,则选择器包含一个按钮,允许您将所选颜色的代码复制到剪贴板。
颜色选择器项的形状、大小和间距都可以进行修改。有一个内置的对话框可以用于在预制的对话框中显示 ColorPicker,但您也可以创建自己的对话框,并将 ColorPicker 放在您自己的自定义对话框中。下面的示例展示了 ColorPicker 的一些变体。

入门
在您的 **Flutter** 项目的 pubspec.yaml 文件中,添加以下依赖项:
dependencies:
...
color_picker:
在您的库文件中添加以下导入:
import 'package:color_picker/color_picker.dart';
示例应用程序
要尝试在设备或模拟器上使用 ColorPicker 的基本示例,请克隆 ColorPicker 存储库并运行示例。
cd example/
flutter run --release
结果是一个基本的默认选择器,以及另一个在对话框中打开的选择器,具有更多选项。

在线 Web 示例
您还可以通过 此处 尝试 ColorPicker 的实时 Web 示例。通过 Web 演示,您可以修改 ColorPicker 的大部分 API 值,并将其用作查找适合您应用程序的设置和样式的工具。
Web 演示的源代码,它只是比随包捆绑的基本示例更详细一些,可以在 此处 找到。

ColorPicker 简介
在普通的 StatefulWidget 中定义一个 Color 变量并为其设置初始值。
class _ColorPickerPageState extends State<ColorPickerPage> {
Color screenPickerColor;
@override
void initState() {
super.initState();
screenPickerColor = Colors.blue[500];
}
在您的 build 方法中添加 ColorPicker,例如可以放在 ListView 或 Column 中。为其提供起始颜色、heading 和 subHeading,以及必需的 onColorChanged 回调函数。使用回调中的颜色在 setState() 中修改 screenPickerColor,使其成为颜色选择器中选定的颜色。
ColorPicker(
color: screenPickerColor,
onColorChanged: (Color color) =>
setState(() => screenPickerColor = color),
heading: Text(
'Select color',
style: Theme.of(context).textTheme.subtitle1,
),
subHeading: Text(
'Select color shade',
style: Theme.of(context).textTheme.subtitle1,
),
),
结果将如下所示:

如果需要,您可以更改选择项的样式和大小。让我们将其设置为圆形:
ColorPicker(
size: 44,
borderRadius: 22,
color: screenPickerColor,
onColorChanged: (Color color) =>
setState(() => screenPickerColor = color),
:
),
您可以像 ColorPicker 内部使用的那样,使用相同的 ColorIndicator 小部件作为颜色指示器。这里我们在 ListTile 中将其用作其 trailing 属性来显示选定的颜色。ColorPicker 还包含 ColorTools,您可以使用它来显示标准的 Material 颜色的名称及其色调索引值。可选地,它还可以返回 Flutter 风格的十六进制颜色代码。我们在 ListTile 的 subtitle 属性中使用它来描述选定的颜色。
ListTile(
title: const Text('Select color above to change this color'),
subtitle: Text(
ColorTools.colorNameAndHexCode(screenPickerColor),
),
trailing: ColorIndicator(
height: 44,
width: 44,
borderRadius: 22,
color: screenPickerColor,
),
),
此设置将产生圆形的颜色选择项,以及一个独立的选定颜色指示器。

ColorPicker 作为对话框
颜色选择器的常见用例是显示一个颜色选择小部件,并允许用户在对话框中选择新颜色或取消颜色选择。ColorPicker 带有一个内置对话框,可用于此目的。或者,您也可以仅使用 ColorPicker 小部件来构建自己的基于它的对话框。
在对话框示例中,我们将展示更多内置的选择器选项,并将一些自定义颜色添加到 ColorPicker 的 **Custom** 颜色部分。
首先,我们定义自定义颜色,并从单个颜色定义中,通过使用 ColorTools.createPrimaryColor 或 ColorTools.createAccentColor(用于定义的颜色的强调色样本)来创建原始颜色和强调色样本。然后,我们将这些颜色样本添加到 ColorSwatch Map 中,并将其映射到我们自定义的颜色样本名称。
// Define some custom colors.
static const Color googlePrimary = Color(0xFF6200EE);
static const Color googlePrimaryVariant = Color(0xFF3700B3);
static const Color googleSecondary = Color(0xFF03DAC6);
static const Color googleSecondaryVariant = Color(0xFF018786);
static const Color googleError = Color(0xFFB00020);
static const Color googleErrorDark = Color(0xFFCF6679);
static const Color mrBlue = Color(0xFF174378);
// Make a custom color swatch to name map from the above custom colors.
final Map<ColorSwatch<Object>, String> colorsNameMap =
<ColorSwatch<Object>, String>{
ColorTools.createPrimaryColor(googlePrimary): 'G Purple',
ColorTools.createPrimaryColor(googlePrimaryVariant): 'G Purple Variant',
ColorTools.createAccentColor(googleSecondary): 'G Teal',
ColorTools.createAccentColor(googleSecondaryVariant): 'G Teal Variant',
ColorTools.createPrimaryColor(googleError): 'G Error',
ColorTools.createPrimaryColor(googleErrorDark): 'G Error Dark',
ColorTools.createPrimaryColor(mrBlue): 'MrBlue',
};
我们还创建了一个 Map,将所有 ColorPickerSwatch 枚举值映射到一个布尔值,该值定义了我们想要在 ColorPicker 中显示的样本。在下面的示例中,我们包括了 Material 原始颜色、强调色以及上述自定义颜色,加上允许我们选择任何颜色的 HSV 色轮。我们没有包含将原始颜色和强调色合并在同一选择器中的选择器,也不显示黑色和白色及其近黑和近白色调的选择器。
static final Map<ColorPickerSwatch, bool> swatchesAvailable =
<ColorPickerSwatch, bool>{
ColorPickerSwatch.both: false,
ColorPickerSwatch.material: true,
ColorPickerSwatch.accent: true,
ColorPickerSwatch.bw: false,
ColorPickerSwatch.custom: true,
ColorPickerSwatch.any: true,
};
我们为对话框选定的颜色 dialogPickerColor 添加了一个变量,并为其设置了一个初始值。
class _ColorPickerPageState extends State<ColorPickerPage> {
Color screenPickerColor;
Color dialogPickerColor;
@override
void initState() {
super.initState();
screenPickerColor = Colors.blue[500];
dialogPickerColor = Colors.red[700];
}
我们使用另一个 ListTile 来显示一个 ColorIndicator,这次我们对其进行了一些不同的样式设置。我们还使用其 onSelect 回调来打开一个带有另一个 ColorPicker 的对话框。在我们打开对话框之前,我们存储了当前的 dialogPickerColor 颜色,我们打算通过对话框更改它。这样,如果用户取消对话框,我们就可以恢复此颜色值。
ListTile(
title: const Text('Click this color to change it in a dialog'),
subtitle: Text(
ColorTools.colorNameAndHexCode(
dialogPickerColor,
colorSwatchNameMap: colorsNameMap,
),
),
trailing: ColorIndicator(
height: 40,
width: 40,
borderRadius: 3,
color: dialogPickerColor,
onSelect: () async {
final Color _colorBeforeDialog = dialogPickerColor;
if (!(await colorPickerDialog())) {
setState(() {
dialogPickerColor = _colorBeforeDialog;
});
}
},
),
),
colorPickerDialog 是一个异步布尔函数,如果用户通过 **Select** 按钮关闭了对话框选择器,则返回 true。如果选择了 **Cancel** 或用户通过点击对话框外部将其关闭,则返回 false。
Future<bool> colorPickerDialog() async {
return ColorPicker(
color: dialogPickerColor,
onColorChanged: (Color color) =>
setState(() => dialogPickerColor = color),
showNameSelected: true,
size: 40,
borderRadius: 3,
padding: 8,
spacing: 3,
runSpacing: 3,
heading: Text(
'Select color',
style: Theme.of(context).textTheme.subtitle1,
),
subHeading: Text(
'Select color shade',
style: Theme.of(context).textTheme.subtitle1,
),
subWheelHeading: Text(
'Selected color and its material like shades',
style: Theme.of(context).textTheme.subtitle1,
),
swatchAvailable: swatchesAvailable,
colorSwatchNameMap: colorsNameMap,
).showPickerDialog(
context,
constraints:
const BoxConstraints(minHeight: 475, minWidth: 480, maxWidth: 480),
);
}
上面的示例使用了一些额外的样式属性,但最重要的是它使用了 showPickerDialog 方法在对话框中显示定义的 ColorPicker。对话框需要一个 context,所以我们将其传递给它。
我们还为对话框定义了尺寸约束。如果未定义尺寸约束,它将自动调整大小以适应对话框内容。使用约束可以使对话框在内容大小稍有变化时保持相同的大小,因为您在启用的不同选择器类型之间切换。当您使用选择器切换选择器类型时,对话框大小不变会更好。特别是色轮选择器通常需要更大的空间。色轮大小也可以自定义,但如果做得非常小,用触摸操作会更困难,准确性也更低。
上述设置的最终结果是,在 ListTile 中,可以单击 trailing 颜色指示器小部件来打开一个对话框,为 trailing ColorIndicator 颜色选择新颜色。
当对话框中的 dialogPickerColor 颜色发生变化时,ColorIndicator 的颜色也会交互式地变化。如果选择被取消,ColorIndicator 的原始颜色将被恢复。

作为一项额外的练习,尝试将 dialogPickerColor 值连接到 AppBar 的 backgroundColor 属性。你成功了吗?发生了什么?
:
appBar: AppBar(
backgroundColor: dialogPickerColor,
elevation: 1,
centerTitle: true,
title: const Text('Color Picker Simple Demo'),
),
正如下面所示,现在当您在对话框中选择颜色时,对话框中的选定颜色会更改 AppBar 的颜色,并且取消它也会恢复应用栏颜色,**非常酷!**
您可以将颜色连接到主题颜色,并交互式地修改应用程序的主题颜色值,但这超出了本示例的范围。

深入了解
以上介绍是对捆绑示例的讲解,请参阅示例部分获取其完整的源代码。
ColorPicker 还有更多配置选项。请参阅 API 参考指南以获取更多信息。您还可以研究更完整的 实时 Web 示例 及其 源代码。