← 返回索引

范围:组件配色、渐变与遮罩所需的 Colors 与 UIRenderUtil 选型、常量与方法的实际行为,包括 lerp 的插值通道数、darken 对半透明色的处理(含注释与实现不一致的已知疑惑)、alpha() 的乘法语义。

前置:核心概念。


Colors 与 UIRenderUtil 的选型

两个类都在 xianfish.fluentui.client.ui.util 包,职责分为颜色计算与渲染辅助两类:

  • Colors 是颜色数学库:语义调色板常量(白、黑、蓝、灰及其透明变体)+ 两个插值/变暗函数。凡是“在两个颜色之间过渡““向黑色压暗“这类纯计算,使用该类。
  • UIRenderUtil 是渲染工具类:遮罩/强调色常量(COLOR_ 前缀)+ 按比例缩放 alpha 的 alpha() + 四通道 lerpColor()。凡是“给现成颜色乘一层透明度““渲染层常用的半透明黑“这类渲染辅助,使用该类。

选型规则:业务配色与动画取色使用 Colors;遮罩、压暗与渲染辅助使用 UIRenderUtil。两者都有四通道插值(Colors.lerp 与 UIRenderUtil.lerpColor 行为一致),任一均可;新代码建议统一使用 Colors.lerp。


Colors

常量

常量值含义
WHITE0xFFFFFFFF不透明白
WHITE_500x80FFFFFF50% 白
WHITE_200x33FFFFFF20% 白
BLACK_500x8000000050% 黑(标准遮罩)
BLACK_750xC000000075% 黑(深遮罩)
BLUE0xFF3B82F6主题蓝(与 UIRenderUtil.COLOR_BLUE_ACCENT 同值)
BLUE_500x803B82F650% 主题蓝
BLUE_DARK0xFF1D4ED8深蓝(与 COLOR_BLUE_DARK 同值)
GRAY_300x4D80808030% 灰
GRAY_500x8080808050% 灰

选择建议:界面语义色(“这是主题蓝”“这是标准遮罩”)按上表名字取;需要 COLOR_ 系的悬停蓝、浅蓝等渲染专用色时,从 UIRenderUtil 常量表获取。

lerp 四通道插值

// 两色之间的匀速插值——渐变、悬停高亮、动画取色都用它
int blended = Colors.lerp(colorA, colorB, t);   // t ∈ [0,1],越界由调用方自控

Colors.lerp(a, b, t) 将 ARGB 四个通道各自线性插值后拼回,红、绿、蓝之外,alpha 也参与插值。因此从不透明色插到透明色时,中间帧的透明度是渐变的,不会整段跳变。t 不在函数内钳制:传 0.5f 得中点,负数或大于 1 由调用方的上层逻辑负责。

darken

int darker = Colors.darken(color, 0.3f);   // t=0 原样,t=1 纯不透明黑

darken(color, t) 先把 t 钳到 [0, 1],然后执行 lerp(color, 0xFF000000, t),朝不透明的纯黑 0xFF000000 插值。

对带透明度的颜色(alpha 不是 0xFF)调用 darken 时,t 钳 0–1 后朝 0xFF000000 插值;由于 lerp 四通道都插,alpha 也从原值朝 255 变化,因此半透明黑压暗后变得更不透明。方法头注释写的是“向黑色加深(保留透明度不变)“,与实现不符,属已知的注释失真;需要“只压 RGB、锁死 alpha“的语义时,现有 darken 不提供,需自行 mask 或改用其他写法。验证方式:darken(0x80000000, 1f) 返回 0xFF000000(alpha 从 0x80 变 0xFF),与注释字面矛盾,文档与调用以代码行为为准;机制细节与注释实现差异的深挖见工具类。


UIRenderUtil

常量

常量值含义
COLOR_BLACK_SEMI0x80000000半透明黑(与 Colors.BLACK_50 同值)
COLOR_BLACK_750xC000000075% 黑(与 Colors.BLACK_75 同值)
COLOR_BLACK_500x8000000050% 黑(与 SEMI 同值,两个名字一个数)
COLOR_BLACK_250x4000000025% 黑(浅遮罩)
COLOR_BLACK_120x1F000000~12% 黑(极浅压暗)
COLOR_BLUE_ACCENT0xFF3B82F6主题蓝(与 Colors.BLUE 同值)
COLOR_BLUE_ACCENT_SEMI0x803B82F6半透明主题蓝(与 Colors.BLUE_50 同值)
COLOR_BLUE_DARK0xFF1D4ED8深蓝(与 Colors.BLUE_DARK 同值)
COLOR_BLUE_LIGHT0xFF60A5FA浅蓝(仅此表有)
COLOR_BLUE_HOVER0xFF2563EB悬停蓝(仅此表有)
COLOR_WHITE0xFFFFFFFF不透明白(与 Colors.WHITE 同值)
COLOR_WHITE_SEMI0x80FFFFFF半透明白(与 Colors.WHITE_50 同值)

选择建议:遮罩梯度(12/25/50/75)与悬停/浅蓝这类渲染态色从本表取;与 Colors 同值的条目可在两处任选,但不得在两处写入不同的数值;同名语义以本表与 Colors.java 当前源码为准。

alpha

// 给现成颜色乘一层透明度——淡出、遮罩渐隐用它
int semi = UIRenderUtil.alpha(0xFF3B82F6, 0.5f);   // 不透明蓝 → alpha 变 0x80

alpha(color, factor) 将颜色当前的 alpha 乘以 factor 后写回,RGB 不变。对不透明色,0.5f 得半透明;对已经半透明的色,效果为“再乘一层“(0.5 的一半是 0.25),不是“设成 50%“;需要设定语义时由调用方算好 factor 或改用常量。方法参数名 alpha 易被理解为“设为该 alpha”,实际按乘法理解:alpha() 的实现体即 Math.round(alpha * ((color >> 24) & 0xFF)),确为乘积。工具类机制的更多细节见工具类。

lerpColor

lerpColor(from, to, t) 与 Colors.lerp 行为一致:ARGB 四通道各自插值后拼回(内部 lerpComponent 即 round(a + (b-a)*t))。新代码使用 Colors.lerp;修改其中一处的通道算法时,另一处必须同步修改,否则文档与运行时会出现互相矛盾的插值结果。


不变量

  1. lerp 与 lerpColor 都是四通道含 alpha。任何“只插 RGB“的改法都破坏颜色动画的透明度渐变。
  2. darken 的行为按代码不按注释:t 钳 0–1、向 0xFF000000 四通道 lerp,半透明输入 alpha 会变大;注释“保留透明度不变“与实现不一致是已知疑惑,调用方若需锁 alpha 必须自行处理。
  3. alpha() 是乘法缩放,对半透明输入是叠乘不是设值。
  4. 两篇常量真值同源:两张表逐行核对过 Colors.java 与 UIRenderUtil.java 全文;工具类的机制深挖可各留真值表,但取值不得与这两张表矛盾,修改源码常量时两篇同步。

连带影响

  • 改 Colors.lerp 的通道数或拼装顺序:波及所有颜色动画(developer.Animation.md 的示例、Button/ItemView 的悬停插值、一切 lerp(normal, hover, t) 调用点),透明渐变会跳变或错位。
  • 改 darken 的目标色或钳制:波及所有压暗调用;若把目标从 0xFF000000 改成保留 alpha 的写法,注释与实现的已知疑惑消失,但既有依赖“压暗同时变实“的视觉要复测。
  • 改任一常量字面值:波及该常量的全部引用组件;同值双名(如 BLACK_50 与 COLOR_BLACK_SEMI)只改一边会造成两处遮罩深浅不一致;修改时需在全库搜索该十六进制值。
  • 改 alpha() 的乘法语义:波及淡出/遮罩叠乘的组件,把乘法改成设值会让半透明输入的叠乘效果消失。
  • 只改 lerp 或只改 lerpColor:两套插值行为分裂,组件按所用工具分裂为两种行为,两边必须同改(不变量 4)。

相关文档

  • 动画:Animator 与 Colors.lerp 配对做颜色动画
  • 核心概念:链式 API 与元素层次
  • 工具类:工具类机制与注释实现差异的深挖(常量真值同源核对)