You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何获取Material 3色调调色板

如何使用Material 3生成的色调调色板

首先明确:Material 3的ColorScheme里的颜色(比如primary)是单一颜色值,并非完整的色调调色板。要获取生成的全色调调色板,需要从主题构建器导出的文件直接调用调色板对象,或者手动将调色板集成到ThemeData中。

方法1:直接调用导出的调色板文件

从Material 3主题构建器导出的代码里,会包含生成的各个色调调色板(比如primaryPalette、secondaryPalette这类映射对象),直接调用对应色调即可:

// 示例:调用主色调调色板的50号色调
primaryPalette[50]
// 调用主色调调色板的900号色调
primaryPalette[900]

方法2:集成调色板到ThemeData,通过上下文访问

如果想通过Theme.of(context)访问调色板,需要自定义ThemeExtension来暴露调色板:

  1. 定义主题扩展类:
class PaletteExtension extends ThemeExtension<PaletteExtension> {
  const PaletteExtension({
    required this.primary,
    required this.secondary,
    required this.tertiary,
    required this.neutral,
  });

  final Map<int, Color> primary;
  final Map<int, Color> secondary;
  final Map<int, Color> tertiary;
  final Map<int, Color> neutral;

  @override
  ThemeExtension<PaletteExtension> copyWith({
    Map<int, Color>? primary,
    Map<int, Color>? secondary,
    Map<int, Color>? tertiary,
    Map<int, Color>? neutral,
  }) {
    return PaletteExtension(
      primary: primary ?? this.primary,
      secondary: secondary ?? this.secondary,
      tertiary: tertiary ?? this.tertiary,
      neutral: neutral ?? this.neutral,
    );
  }

  @override
  ThemeExtension<PaletteExtension> lerp(
      ThemeExtension<PaletteExtension>? other, double t) {
    if (other is! PaletteExtension) return this;
    return PaletteExtension(
      primary: _lerpColorMap(primary, other.primary, t),
      secondary: _lerpColorMap(secondary, other.secondary, t),
      tertiary: _lerpColorMap(tertiary, other.tertiary, t),
      neutral: _lerpColorMap(neutral, other.neutral, t),
    );
  }

  Map<int, Color> _lerpColorMap(Map<int, Color> a, Map<int, Color> b, double t) {
    return a.map((key, color) => MapEntry(
          key,
          Color.lerp(color, b[key] ?? color, t) ?? color,
        ));
  }
}
  1. 创建ThemeData时添加该扩展:
// 从导出文件中获取生成的四个调色板对象
final themeData = ThemeData(
  colorScheme: ColorScheme.fromSeed(seedColor: primaryPalette[500]!),
  useMaterial3: true,
  extensions: [
    PaletteExtension(
      primary: primaryPalette,
      secondary: secondaryPalette,
      tertiary: tertiaryPalette,
      neutral: neutralPalette,
    ),
  ],
);
  1. 在Widget中通过上下文调用:
final palette = Theme.of(context).extension<PaletteExtension>()!;
// 获取主色调的50号颜色
Color lightPrimary = palette.primary[50]!;
// 获取中性色调的800号颜色
Color darkNeutral = palette.neutral[800]!;

为什么之前的调用无效?

Theme.of(context).colorScheme.primary返回的是单个Color实例(默认对应调色板中的500号色调,是亮色模式下的主色),它本身没有[50]或shade50属性,自然无法调用。只有完整的调色板映射对象才包含所有色调的颜色值。

内容的提问来源于stack exchange,提问作者Guy Luz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:47:32