You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter中colorScheme的正确使用场景、自定义方法及与Color()的使用时机咨询

Flutter中colorScheme的正确使用场景、自定义方法及与Color()的使用时机咨询

作为常年泡在Flutter项目里的老开发,太懂你这种后端转前端面对UI配色的迷茫了!尤其是colorScheme这东西,看着一堆属性名完全不知道对应啥场景,不如直接写Color()来得痛快。我给你掰扯清楚,保证你看完就知道该怎么选。

一、优先用colorScheme的场景(为啥不推荐直接写死Color())

说真的,只要你的项目是正经做产品而非快速Demo,我都建议优先用colorScheme,原因如下:

  • 统一项目视觉风格,改主题不用疯批式找代码:比如你把APP的提示文本统一用colorScheme.onSurfaceVariant,哪天产品说要把所有提示色从浅灰改成偏蓝的灰,你只需要在colorScheme里改这一个属性,所有用了它的组件自动同步,不用几十个页面挨个找Colors.grey或者Color(0xFF999999)去改。
  • 适配明暗模式不用自己写判断:比如colorScheme.surface在亮模式是浅灰,暗模式自动变成深灰,你直接用的话,系统切换明暗时组件颜色自动适配,不用自己写一堆Theme.of(context).brightness == Brightness.dark ? ... : ...的判断逻辑。
  • 自带对比度保障,避免踩UI坑:Google定义的colorScheme里的每对属性(比如primaryonPrimary)都是经过对比度校验的,比如主色调primary是深蓝色,onPrimary默认是白色,保证文字在主色调上清晰可读,不用自己瞎配颜色导致用户看不清文字。
  • 支持多主题切换,扩展性拉满:要是以后产品要加个“夜间模式”“护眼模式”,你只需要定义对应的colorScheme,切换时整个APP的配色就全换了,要是用一堆硬编码的Color(),那改起来绝对让你怀疑人生。

二、适合直接用Color()的场景

当然不是所有情况都要硬套colorScheme,这些场景直接写Color()更高效:

  • 完全自定义的设计,不遵循Material规范:比如设计师给了一套和Material Design八竿子打不着的配色,某个按钮的颜色是独一份的、不会在其他地方复用的特殊色,直接写Color(0xFFxxxxxx)就行,不用硬塞进colorScheme里凑数。
  • 临时的局部特殊配色:比如某个页面里有个小图标,设计师要求用一个很奇怪的颜色,这个颜色只在这个图标上用,那直接写Color()就好,没必要为了这一个颜色去修改全局的colorScheme。
  • 快速原型开发:写Demo、验证功能的时候,效率优先,直接用Color()快速搭出界面,等后期做UI规范统一的时候再换成colorScheme的属性。

三、给后端同学的colorScheme属性大白话翻译

你说看不懂colorScheme里的属性啥意思,我给你把常用的几个翻译成大白话,对应到具体UI场景:

  • primary:APP的主色调,比如导航栏、主按钮、选中状态的标签页
  • onPrimary:在主色调上显示的文字/图标颜色(比如蓝色按钮上的白色文字)
  • secondaryContainer:辅助色容器,比如次要按钮的背景、选中菜单项的背景
  • onSurface:页面背景上的主要文字颜色(比如正文内容)
  • onSurfaceVariant:页面背景上的次要文字/提示文字(就是你说的hintText,比正文颜色浅一级)
  • surface:页面背景色、卡片背景色
  • error:错误提示、输入框错误状态的边框颜色
  • onError:错误颜色上的文字颜色(比如红色错误提示框上的白色文字)

四、自定义colorScheme的简单方法(后端同学也能快速上手)

其实自定义colorScheme没你想的复杂,给你两个常用的方式:

1. 用seedColor快速生成整套配色

Google提供了ColorScheme.fromSeed()方法,你只需要指定一个主色(seedColor),它会自动生成一套符合Material规范的配色,还能自动适配明暗模式:

MaterialApp(
  // 亮模式主题
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: Color(0xFF2196F3), // 你的主色调,比如蓝色
      brightness: Brightness.light,
      // 可以单独覆盖某个属性,比如提示文字的颜色
      onSurfaceVariant: Color(0xFF666666),
    ),
  ),
  // 暗模式主题
  darkTheme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: Color(0xFF2196F3),
      brightness: Brightness.dark,
      onSurfaceVariant: Color(0xFFAAAAAA),
    ),
  ),
  home: YourHomePage(),
);

2. 手动指定每个属性(完全自定义)

如果你对自动生成的配色不满意,可以手动指定每个属性,比如:

ThemeData(
  colorScheme: ColorScheme.light(
    primary: Color(0xFF2196F3), // 主色
    secondary: Color(0xFF03DAC6), // 辅助色
    onSurfaceVariant: Color(0xFF757575), // 提示文字颜色
    surface: Color(0xFFF5F5F5), // 页面背景色
    // 其他属性如果不指定会用默认值,也可以自己加
  ),
);

3. 在组件里使用自定义的colorScheme

在组件里通过Theme.of(context)拿到colorScheme就行:

Text(
  '提示文本',
  style: TextStyle(
    fontSize: 10,
    color: Theme.of(context).colorScheme.onSurfaceVariant,
  ),
);

五、一句话总结怎么选

  • 要是这个颜色是APP里复用的、属于固定UI角色的(主色、提示色、背景色等),果断用colorScheme.xxx
  • 要是这个颜色是一次性的、特殊的、和主题无关的,直接用Color()就完事儿。

要是还有啥具体场景拿不准,比如某个组件该用哪个colorScheme属性,随时提出来,我给你对应上!

火山引擎 最新活动