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

【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://github.com/wpbkj/flutter_wpbkj_express
该项目中自定义了主题色为Colors.blueAccent可供参考

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中的自定义Controller是指可以控制和管理特定组件状态的类。通过自定义Controller,我们可以实现对组件的状态进行监听、更新和控制。 在Flutter中,常用的自定义Controller是StatefulWidget的Controller,也称为StateController。StateController通常包含一个State对象,用于管理组件的状态,并提供一些方法来更新状态和通知组件重新构建。 下面是一个简单的示例,展示了如何创建一个自定义的Controller来管理一个计数器的状态: ```dart class CounterController { int _count = 0; int get count => _count; void increment() { _count++; } } ``` 在上面的示例中,CounterController包含一个私有变量_count来保存计数器的值,并提供了一个公共方法increment来增加计数器的值。通过get方法count,我们可以获取当前计数器的值。 在使用自定义Controller时,通常需要将其与StatefulWidget配合使用。下面是一个使用CounterController的示例: ```dart class CounterWidget extends StatefulWidget { @override _CounterWidgetState createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { final CounterController _controller = CounterController(); @override Widget build(BuildContext context) { return Column( children: [ Text('Count: ${_controller.count}'), RaisedButton( child: Text('Increment'), onPressed: () { setState(() { _controller.increment(); }); }, ), ], ); } } ``` 在上面的示例中,CounterWidget使用CounterController来管理计数器的状态。在build方法中,我们可以通过_controller.count获取当前计数器的值,并通过_controller.increment方法来增加计数器的值。当点击按钮时,我们调用setState方法来通知Flutter框架重新构建组件。 通过自定义Controller,我们可以更好地管理和控制组件的状态,使代码更加模块化和可维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值