本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
样式与主题
CrossFly 中的外观可以归结为框架自身的一句助记词:
Skin = 结构 / 渲染器 · Theme = 按模式划分的语义角色。
三个不同的职责相互协作。
1. 按状态划分的样式(default / focused / pressed)
每个 Component 都可以拥有最多三种样式,框架会根据交互在每一帧
选择正确的那一种。这就是为什么一个按钮被按下时会“下沉”,而你无需编写任何动画。
comp.style(normal).focusedStyle(focado).pressedStyle(apertado);
2. Skin —— 形态工厂
Skin 定义结构:圆角半径、边框粗细、间距、默认图标。有
MaterialSkin、IOSSkin、FlutterSkin。自定义 Skin 会覆盖形态/间距 —— 但从不
覆盖颜色。更换全局 Skin 会为所有组件重新“穿衣”。
3. Theme + ColorScheme —— 语义角色
颜色来自角色(PRIMARY、SURFACE、ON_SURFACE、ERROR、TITLE、HINT……),它们被解析到当前的亮色/暗色
模式,其来源是一个从种子色生成的 ColorScheme(Material You)。
Styles.theme(0xFF6750A4, ThemeMode.DARK); // 一次调用即在暗色模式下为一切设定主题
最强大之处:在运行时切换主题而无需重建 UI
这里有一个微妙之处,让亮色/暗色模式变得轻而易举:
- 样式的颜色不是“冻结”的值 —— 它们是
PalColor,是对调色板的活 引用。 - 存在一个全局样式版本计数器(
styleVersion)。当应用新的方案 / 切换模式时,框架会递增版本号并在所有打开的窗口上重新应用主题 —— 每个基于PalColor的样式都会在下一帧重新解析其颜色。没有任何组件被 销毁再重建。
作为补充,那些样式会因模式而改变形态的组件会注册如何自我重新样式化
(onRestyle/styled),而 restyle() 会就地重新应用子树:
Label titulo = new Label("Bem-vindo").styled(() -> Styles.theme().label(LabelRole.TITLE));
// ...切换模式时,框架重新评估该 provider 并重新着装,无需重建 Label。
Styles.toggleDarkMode();
为什么采用这种架构
- 将形态(Skin)与颜色(Theme)分离,让你可以独立更换视觉标识与 色板 —— 并在不改动 Skin 的情况下适配亮色/暗色。
PalColor+ 版本把“切换主题”从“重建整棵树”变成了“在下一帧 重新解析颜色” —— 廉价且无闪烁。
参见
这个页面有帮助吗?感谢你的反馈!