【Flutter】如何自定义Flutter MaterialApp主题色(primarySwatch)?

【Flutter】如何自定义Flutter MaterialApp主题色(primarySwatch)?

wpbkj
2023-02-09 / 294 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年07月27日,已超过210天没有更新,若内容或图片失效,请发送邮件至admin@wpbkj.com。

【Flutter】如何自定义Flutter MaterialApp主题色(primarySwatch)?

问题

在实际使用Flutter进行MaterialApp开发时,大都遇到一个问题,Flutter提供的可供选择的主题色(MaterialColor)很少,仅有如下几种:

MaterialColor red
MaterialColor pink
MaterialColor purple
MaterialColor deepPurple
MaterialColor indigo
MaterialColor blue
MaterialColor lightBlue
MaterialColor cyan
MaterialColor teal
MaterialColor green
MaterialColor lightGreen
MaterialColor lime
MaterialColor yellow
MaterialColor amber
MaterialColor orange
MaterialColor deepOrange
MaterialColor brown
MaterialColor grey
MaterialColor blueGrey

那么我们品牌有自己专属的品牌色或我有自己钟爱的颜色怎么自由设置主题色呢?


研究

通过material\colors.dart文件我们可以发现,其中关于MaterialColor的描述是这样的

/// Defines a single color as well a color swatch with ten shades of the color.
///
/// The color's shades are referred to by index. The greater the index, the
/// darker the color. There are 10 valid indices: 50, 100, 200, ..., 900.
/// The value of this color should the same the value of index 500 and [shade500].
///
/// See also:
///
///  * [Colors], which defines all of the standard material colors.
class MaterialColor extends ColorSwatch<int> {
  /// Creates a color swatch with a variety of shades.
  ///
  /// The `primary` argument should be the 32 bit ARGB value of one of the
  /// values in the swatch, as would be passed to the [Color.new] constructor
  /// for that same color, and as is exposed by [value]. (This is distinct from
  /// the specific index of the color in the swatch.)
  const MaterialColor(super.primary, super.swatch);

  /// The lightest shade.
  Color get shade50 => this[50]!;

  /// The second lightest shade.
  Color get shade100 => this[100]!;

  /// The third lightest shade.
  Color get shade200 => this[200]!;

  /// The fourth lightest shade.
  Color get shade300 => this[300]!;

  /// The fifth lightest shade.
  Color get shade400 => this[400]!;

  /// The default shade.
  Color get shade500 => this[500]!;

  /// The fourth darkest shade.
  Color get shade600 => this[600]!;

  /// The third darkest shade.
  Color get shade700 => this[700]!;

  /// The second darkest shade.
  Color get shade800 => this[800]!;

  /// The darkest shade.
  Color get shade900 => this[900]!;
}

通过官方给MaterialColor类的注释我们不难发现,要自定义MaterialColor我们需要传入一个颜色初始值primary及从亮到暗共十个级别的Map<int, Color>
这里有一张来自Flutter官方给出的Colors.blue的颜色卡
Colors.blue from flutter.github.io
可以看出primary应该就是就是我们想要的主要颜色,同时也是shade500的值
下面我们只需要解决如何定义给出包含这10个级别的颜色即可

解决办法

目前公认的解决办法有如下几种

1、函数生成自定义色板

  MaterialColor createMaterialColor(Color color) {
    List strengths = <double>[.05];
    Map<int, Color> swatch = {};
    final int r = color.red, g = color.green, b = color.blue;

    for (int i = 1; i < 10; i++) {
      strengths.add(0.1 * i);
    }
    strengths.forEach((strength) {
      final double 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(color.value, swatch);
  }

使用时仅需要在设置primarySwatch时调用该函数即可
示例

primarySwatch: createMaterialColor(Colors.blueAccent) // 第一种
primarySwatch: createMaterialColor(Color(0xFF448AFF)) // 第二种,注意为8为16进制,首两位FF代表不透明

2、改变透明值以生成不同亮度级别(不推荐)

注意:并不推荐该种方法,该方法会导致组件变透明而不是颜色深浅

示例

MaterialColor myColor = MaterialColor(0xFF880E4F, color);

Map<int, Color> color =
{
50:Color.fromRGBO(4,131,184, .1),
100:Color.fromRGBO(4,131,184, .2),
200:Color.fromRGBO(4,131,184, .3),
300:Color.fromRGBO(4,131,184, .4),
400:Color.fromRGBO(4,131,184, .5),
500:Color.fromRGBO(4,131,184, .6),
600:Color.fromRGBO(4,131,184, .7),
700:Color.fromRGBO(4,131,184, .8),
800:Color.fromRGBO(4,131,184, .9),
900:Color.fromRGBO(4,131,184, 1),
};

使用时赋myColorprimarySwatch即可

3、手动选择不同亮度级别颜色

如果您对颜色有严格要求,可以手动自定义不同亮度颜色,这里不给出示例

结语

实战项目:https://www.wpbkj.com/archives/flutter_wpbkj_express.html
该项目中自定义了主题色为Colors.blueAccent可供参考

本文由WPBKJ原创,转载请声明

3
知识共享许可协议
MySSL 安全签章
TrustAsia 安全签章