ColorPicker

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

ColorPickerAllSize50-upper

不同的颜色选择选项包括:

  1. Material 原始颜色及其色调。ColorPickerSwatch.material
  2. Material 强调色及其色调。ColorPickerSwatch.accent
  3. Material 原始颜色和强调色及其色调,在同一个颜色选择器中。ColorPickerSwatch.both
  4. 黑色和白色,包括近黑和近白色调。ColorPickerSwatch.bw
  5. 自定义的 Material 风格颜色及其色调,由您定义和命名。ColorPickerSwatch.custom
  6. 一个 HSV 色轮选择器,允许您选择任何颜色。所选颜色的 Material 原始颜色色调会自动计算。ColorPickerSwatch.any

当您显示一种以上的颜色样本选择工具时,一个滑块允许您选择要使用的工具。您可以配置颜色选择器以包含以上任何颜色样本。显示选项 1 和 2,以及选项 3 并不十分有用,它们可以作为显示 Material 原始颜色和强调颜色的可选方式。

您可以为选择器提供标题和副标题,通常是具有适当样式的 Text 小部件。您还可以定义 Material 色调是否可以选择,以及所选颜色的名称和值是否在选择器中显示。如果显示了值,则选择器包含一个按钮,允许您将所选颜色的代码复制到剪贴板。

颜色选择器项的形状、大小和间距都可以进行修改。有一个内置的对话框可以用于在预制的对话框中显示 ColorPicker,但您也可以创建自己的对话框,并将 ColorPicker 放在您自己的自定义对话框中。下面的示例展示了 ColorPicker 的一些变体。

ColorPickerAllSize50-lower

入门

在您的 **Flutter** 项目的 pubspec.yaml 文件中,添加以下依赖项:

dependencies:
  ...
  color_picker:

在您的库文件中添加以下导入:

import 'package:color_picker/color_picker.dart';

示例应用程序

要尝试在设备或模拟器上使用 ColorPicker 的基本示例,请克隆 ColorPicker 存储库并运行示例。

cd example/
flutter run --release

结果是一个基本的默认选择器,以及另一个在对话框中打开的选择器,具有更多选项。

ColorPickerSimpleDemo

在线 Web 示例

您还可以通过 此处 尝试 ColorPicker 的实时 Web 示例。通过 Web 演示,您可以修改 ColorPicker 的大部分 API 值,并将其用作查找适合您应用程序的设置和样式的工具。

Web 演示的源代码,它只是比随包捆绑的基本示例更详细一些,可以在 此处 找到。

ColorPickerWeb

ColorPicker 简介

在普通的 StatefulWidget 中定义一个 Color 变量并为其设置初始值。

class _ColorPickerPageState extends State<ColorPickerPage> {
  Color screenPickerColor;

@override
void initState() {
  super.initState();
  screenPickerColor = Colors.blue[500];
}

在您的 build 方法中添加 ColorPicker,例如可以放在 ListViewColumn 中。为其提供起始颜色、headingsubHeading,以及必需的 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,
  ),
),

结果将如下所示:

ColorPicker01

如果需要,您可以更改选择项的样式和大小。让我们将其设置为圆形:

ColorPicker(
  size: 44,
  borderRadius: 22,

  color: screenPickerColor,
  onColorChanged: (Color color) =>
    setState(() => screenPickerColor = color),
 :
),

您可以像 ColorPicker 内部使用的那样,使用相同的 ColorIndicator 小部件作为颜色指示器。这里我们在 ListTile 中将其用作其 trailing 属性来显示选定的颜色。ColorPicker 还包含 ColorTools,您可以使用它来显示标准的 Material 颜色的名称及其色调索引值。可选地,它还可以返回 Flutter 风格的十六进制颜色代码。我们在 ListTilesubtitle 属性中使用它来描述选定的颜色。

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,
  ),
),

此设置将产生圆形的颜色选择项,以及一个独立的选定颜色指示器。

ColorPicker02

ColorPicker 作为对话框

颜色选择器的常见用例是显示一个颜色选择小部件,并允许用户在对话框中选择新颜色或取消颜色选择。ColorPicker 带有一个内置对话框,可用于此目的。或者,您也可以仅使用 ColorPicker 小部件来构建自己的基于它的对话框。

在对话框示例中,我们将展示更多内置的选择器选项,并将一些自定义颜色添加到 ColorPicker 的 **Custom** 颜色部分。

首先,我们定义自定义颜色,并从单个颜色定义中,通过使用 ColorTools.createPrimaryColorColorTools.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 的原始颜色将被恢复。

ColorPickerSimpleDemo

作为一项额外的练习,尝试将 dialogPickerColor 值连接到 AppBarbackgroundColor 属性。你成功了吗?发生了什么?

:
appBar: AppBar(
  backgroundColor: dialogPickerColor,
  elevation: 1,
  centerTitle: true,
  title: const Text('Color Picker Simple Demo'),
),

正如下面所示,现在当您在对话框中选择颜色时,对话框中的选定颜色会更改 AppBar 的颜色,并且取消它也会恢复应用栏颜色,**非常酷!**

您可以将颜色连接到主题颜色,并交互式地修改应用程序的主题颜色值,但这超出了本示例的范围。

ColorPickerSimpleDemoAppBar

深入了解

以上介绍是对捆绑示例的讲解,请参阅示例部分获取其完整的源代码。

ColorPicker 还有更多配置选项。请参阅 API 参考指南以获取更多信息。您还可以研究更完整的 实时 Web 示例 及其 源代码

GitHub

https://github.com/rydmike/color_picker