有 Flutter 的 Material Design 颜色图吗?

Posted

技术标签:

【中文标题】有 Flutter 的 Material Design 颜色图吗?【英文标题】:Is there a map of Material design colors for Flutter? 【发布时间】:2018-03-17 15:41:24 【问题描述】:

我有一个小部件,理想情况下我希望采用基本 Material 颜色并输出一个以该颜色的阴影为主题的小部件。例如:

return new Container(
  color: Colors.pink.shade50,
  child: new Text(
    'hello',
    style: new TextStyle(
      color: Colors.pink.shade100,
    ),
  ),
);

要求我指定两种粉红色。理想情况下,我可以这样做:

Color color = getBaseColorForThisPage(); // returns something like Colors.pink, but on another page, it'll return something like Colors.purple
return new Container(
  color: color.shade50,
  child: new Text(
    'hello',
    style: new TextStyle(
      color: color.shade100,
    ),
  ),
);

有没有办法在调色板中返回材质颜色的“映射”,而不仅仅是一种颜色?当我查看 IntelliJ 中的自动完成功能时,我发现在输入 Colors.pink 后,我可以指定阴影。但是,如果我将颜色设置为变量,例如Color color = Colors.pink,我以后不能做color.shade100color[100]。谢谢!

【问题讨论】:

【参考方案1】:

如果你看一下关于 Flutter 的 Dart 文档here

您会注意到一些 MaterialColor 对象是如何创建的。

显然 Flutter 对 MaterialDesign 有很好的概念,here 描述的大部分颜色已经在 Flutter 主包“package:flutter/material.dart”中预定义。所有这些都可以开箱即用,但是

如果有人仍然想用特定的色调创建自己的 MaterialColor,你可以这样做:

MaterialColor myGreen = const MaterialColor(0xFFAAD400,
  const 
    50 : const Color(hex_value1),
    100 : const Color(hex_value2),
    200 : const Color(hex_value3),
    300 : const Color(hex_value4),
    400 : const Color(hex_value5),
    500 : const Color(hex_value6),
    600 : const Color(hex_value7),
    700 : const Color(hex_value8),
    800 : const Color(hex_value9),
    900 : const Color(hex_value10));

MaterialColor 对象构造函数中的第一个参数是颜色的默认 HEX 值,在本例中为 0xFFAAD400。第二个参数是一个包含所有颜色样本的地图。所有关于 "hex_value1" .... "hex_value10" 的值都需要是不同的颜色。要了解如何选择(创建)这些色板,例如查看here

对于那些不知道如何读取颜色 HEX 值的人,我将在这里发布一些附加信息:

例如,要获得完全不透明的橙色 (0xFFFF9000),您可以使用 常量颜色(0xFFFF9000),其中:

前两个字符 (FF) 与 alpha(透明度)有关,

后两个字符 (FF) 代表红色,

第三个两个字符 (90) 代表绿色,

最后两个 (00) 为蓝色。

谢谢,希望对大家有所帮助

【讨论】:

【参考方案2】:

对不起,我知道这已经有很多很好的答案,但这是我一直用来将任何颜色转换为材质颜色的天真实现,以防有人发现它有用:

import 'package:flutter/material.dart';

Map<int, Color> getSwatch(Color color) 
  final hslColor = HSLColor.fromColor(color);
  final lightness = hslColor.lightness;

  /// if [500] is the default color, there are at LEAST five
  /// steps below [500]. (i.e. 400, 300, 200, 100, 50.) A
  /// divisor of 5 would mean [50] is a lightness of 1.0 or
  /// a color of #ffffff. A value of six would be near white
  /// but not quite.
  final lowDivisor = 6;

  /// if [500] is the default color, there are at LEAST four
  /// steps above [500]. A divisor of 4 would mean [900] is
  /// a lightness of 0.0 or color of #000000
  final highDivisor = 5;

  final lowStep = (1.0 - lightness) / lowDivisor;
  final highStep = lightness / highDivisor;

  return 
    50: (hslColor.withLightness(lightness + (lowStep * 5))).toColor(),
    100: (hslColor.withLightness(lightness + (lowStep * 4))).toColor(),
    200: (hslColor.withLightness(lightness + (lowStep * 3))).toColor(),
    300: (hslColor.withLightness(lightness + (lowStep * 2))).toColor(),
    400: (hslColor.withLightness(lightness + lowStep)).toColor(),
    500: (hslColor.withLightness(lightness)).toColor(),
    600: (hslColor.withLightness(lightness - highStep)).toColor(),
    700: (hslColor.withLightness(lightness - (highStep * 2))).toColor(),
    800: (hslColor.withLightness(lightness - (highStep * 3))).toColor(),
    900: (hslColor.withLightness(lightness - (highStep * 4))).toColor(),
  ;

该函数只是在目标颜色的上方和下方添加相对的亮度。获得最终的材料颜色将是:

final materialColor = MaterialColor(color.value, getSwatch(color));

【讨论】:

感谢此代码,它很有希望,但不幸的是,它不会生成与真正的硬编码材料样本相同的样本,它只是一个不同的样本。我试过了,发现它看起来适合深色(靛蓝),但应用于浅色(橙色)时看起来完全错误。这是我想出的根据简单的主值 Color 确定相应 MaterialColor 的方法: MaterialColor getMaterialSwatch(Color color) return Colors.primaries.firstWhere((element) => element.value == color.value); 是的,抱歉。我前一阵子写了这篇文章,发现无论如何不要到处定义自己的材质颜色是更好的做法,所以我从那以后就没有检查或使用过它。随意创建一个答案并 ping 我,如果你也关心,我会在这个链接中链接到它 这是我找到的更好的解决方案。谢谢!【参考方案3】:

MaterialColor 扩展了ColorSwatch,这有点像Map 的颜色。您可以在任何可以使用Color 的地方使用ColorSwatch 并获得500 色度,但您也可以使用[] 对其进行索引。

要获得所有主要材料色样的List,请使用Colors.primaries

【讨论】:

我必须自己为 ColorSwatch 定义贴图,还是有办法参考 MaterialColor 贴图?到目前为止,这是我拥有的代码 sn-p(为格式化道歉),我必须手动定义颜色的每个阴影:var map = new Map&lt;dynamic, Color&gt;(); map.putIfAbsent(50, () =&gt; Colors.pink[50]); map.putIfAbsent(100, () =&gt; Colors.pink[100]); var colorswatch = new ColorSwatch(500, map); // later setting color: // color: colorswatch[50] 我尝试使用 Colors.primaries 中的颜色,但它们返回 MaterialColor 而不是地图。 我不确定你为什么在这里使用Map。你可以只说ColorSwatch color = Colors.pink;,稍后你可以说color[50]。如果您知道所有色板都是MaterialColor,只需使用MaterialColor 作为color 的类型。 啊,我想我必须实例化一个新的 ColorSwatch 对象(它接受一个地图)!我没有意识到我可以将 ColorSwatch 对象设置为现有的 MaterialColor。谢谢。【参考方案4】:

您可以像这样创建材质颜色:

const MaterialColor primaryColorShades = MaterialColor(
  0xFF181861,
  <int, Color>
    50: Color(0xFFA4A4BF),
    100: Color(0xFFA4A4BF),
    200: Color(0xFFA4A4BF),
    300: Color(0xFF9191B3),
    400: Color(0xFF7F7FA6),
    500: Color(0xFF181861),
    600: Color(0xFF6D6D99),
    700: Color(0xFF5B5B8D),
    800: Color(0xFF494980),
    900: Color(0xFF181861),
  ,
);

【讨论】:

【参考方案5】:

为什么不直接创建自己的材质颜色,这很容易。我还使用一个简单的网站来选择颤振的颜色。 Flutter Doctor Color Picker

【讨论】:

您发布的网站无法将十六进制颜色转换为argb。 问题是 - 如何将 Color 变量转换为 MaterialColor?【参考方案6】:

我们必须为此使用地图:

如果您想创建自己的具有特定色调的 MaterialColor,您可以通过创建自己的 RGBO(红色、绿色、蓝色、不透明度)形式的颜色映射来执行以下操作:

Map<int, Color> colorMap = 
  50: Color.fromRGBO(147, 205, 72, .1),
  100: Color.fromRGBO(147, 205, 72, .2),
  200: Color.fromRGBO(147, 205, 72, .3),
  300: Color.fromRGBO(147, 205, 72, .4),
  400: Color.fromRGBO(147, 205, 72, .5),
  500: Color.fromRGBO(147, 205, 72, .6),
  600: Color.fromRGBO(147, 205, 72, .7),
  700: Color.fromRGBO(147, 205, 72, .8),
  800: Color.fromRGBO(147, 205, 72, .9),
  900: Color.fromRGBO(147, 205, 72, 1),
;
// Green color code: 93cd48 and first two characters (FF) are alpha values (transparency)
MaterialColor customColor = MaterialColor(0xFF93cd48, colorMap); 

如果您有像 93cd48 这样的颜色代码值,那么将其转换为 RGB 值使用 https://www.rapidtables.com/convert/color/hex-to-rgb.html

更多参考:https://medium.com/@jits619/flutter-material-color-conversion-ad1574f25828

https://www.youtube.com/watch?v=U19hRU9e0yw&list=PLQ7fSTYH_bV06SWG1IPnyFbavN5NB_h2o&index=7&t=345s

【讨论】:

【参考方案7】:

聚会有点晚了,但我制作了一个 dart 扩展包,它使用起来超级简单,可以创建完美的 MaterialColor 对象。 https://pub.dev/packages/material_color_gen

使用超级简单:

var newColor = Color(0xFF2929FF).toMaterialColor();

【讨论】:

【参考方案8】:

这是我从某个地方获得的扩展方法,但我找不到在哪里。我还必须进行一些小调整才能让它在较新的、null-safe 版本的 Dart 上工作。

extension ColorConversion on Color 
  MaterialColor toMaterialColor() 
    final List strengths = <double>[.05];
    final Map<int, Color> swatch = ;
    final r = red, g = green, b = blue;

    for (var i = 1; i < 10; i++) 
      strengths.add(0.1 * i);
    

    for (final strength in strengths) 
      final ds = 0.5 - strength;
      swatch[(strength * 1000).round()] = Color.fromRGBO(
        r + ((ds < 0 ? r : (255 - r)) * ds).round(),
        g + ((ds < 0 ? g : (255 - g)) * ds).round(),
        b + ((ds < 0 ? b : (255 - b)) * ds).round(),
        1,
      );
    

    return MaterialColor(value, swatch);
  

【讨论】:

以上是关于有 Flutter 的 Material Design 颜色图吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 上将宽度设置为 Material 小部件?

URI 的目标不存在 'package:flutter/material.dart'

Flutter3.3对Material3设计风格的支持

Flutter:Material App 的标题用在哪里?

Flutter(30):Material组件之DataTable

库 'package:flutter/material.dart' 是遗留的,不应导入到 null 安全库中