样式
概览
本文档说明 style 的字段语义。公开 JSON 使用 camelCase。
相关文档
样式合成顺序
style 是可选 object。当前最终样式合并顺序固定为:
内建默认
theme.styles.all内建默认
theme.styles.<节点 type>当前 Runtime theme
styles.all当前 Runtime theme
styles.<节点 type>当前 Runtime theme 中
styleRefs引用的命名样式节点显式
stylebackend 最小技术兜底
其中:
gui_interface总会先应用一份内建默认 themeRuntime 外部 theme 是可选覆盖层,不是默认值来源
节点显式
style永远按字段覆盖内建默认 theme 和外部 theme未被 theme 和节点显式设置的字段,最后才回落到 backend 最小技术兜底
backend 每次应用样式时会把最终 ResolvedStyle 映射到自己的原生样式对象。style
缺省不等于 backend 默认值;多数正式默认值来自内建默认 theme,backend 只负责实现层安全兜底。
Runtime view debug 叠加的是 backend debug outline:
这层可视化不是
style.margin它不参与布局,不改变
placement、layout、真实 margin 或最终 frame目标是帮助观察控件大小和位置,而不是表达正式 UI 样式
字段表
Key |
类型 |
默认值 |
UI 影响 |
Backend 行为 / 限制 |
|---|---|---|---|---|
|
string, |
|
主体背景色 |
非空且可解析时应用背景色;最终为空时背景透明 |
|
string, |
|
主体背景过渡色 |
与 |
|
enum |
|
背景渐变方向 |
可选值: |
|
integer, |
backend 默认 |
主背景色 stop |
LVGL 背景渐变 stop;仅在配置渐变时有意义 |
|
integer, |
backend 默认 |
过渡色 stop |
LVGL 背景渐变 stop;仅在配置渐变时有意义 |
|
integer, |
|
过渡色透明度 |
LVGL 背景渐变 opacity |
|
string, |
|
文本颜色 |
应用文本颜色 |
|
string enum, |
|
文本水平对齐 |
映射到 backend 文本对齐 |
|
string, |
|
边框颜色 |
若 |
|
string, |
|
line 控件线条颜色 |
应用线条颜色 |
|
string, |
|
arc 弧线颜色 |
应用到 LVGL arc style;indicator 通常写在 |
|
string, |
|
arc 弧线过渡色 |
LVGL backend 对 arc 使用分段绘制近似两色渐变 |
|
string, 必须为 |
内建默认 theme 为 |
文本字体资源 |
parser 展开为 font id;runtime 解析为 backend 可用字体资源;未命中字库时允许对 |
|
number px 或 |
内建默认 theme 为 |
文本字号 |
字段存在时 |
|
number px 或 |
imageFont 第一档尺寸 |
imageFont glyph 尺寸选择 |
只对 |
|
number px 或 |
内建默认 theme 为 |
边框宽度 |
字段显式存在时覆盖 theme;最终无值时 backend 用 |
|
number px 或 |
内建默认 theme 为 |
圆角半径 |
字段显式存在时覆盖 theme;最终无值时 backend 用 |
|
number px 或 |
|
四边内边距 |
作为四边默认值,分方向字段可覆盖 |
|
number px 或 |
|
左内边距 |
若未写则回退到 |
|
number px 或 |
|
右内边距 |
若未写则回退到 |
|
number px 或 |
|
上内边距 |
若未写则回退到 |
|
number px 或 |
|
下内边距 |
若未写则回退到 |
|
number px 或 |
|
四边外边距 |
作为四边默认值,分方向字段可覆盖 |
|
number px 或 |
|
左外边距 |
若未写则回退到 |
|
number px 或 |
|
右外边距 |
若未写则回退到 |
|
number px 或 |
|
上外边距 |
若未写则回退到 |
|
number px 或 |
|
下外边距 |
若未写则回退到 |
|
number px 或 |
内建默认 theme 为 |
阴影尺寸 |
节点省略时继承 theme 层 |
|
number px 或 |
内建默认 theme 为 |
阴影 X 偏移 |
应用阴影 X 偏移 |
|
number px 或 |
内建默认 theme 为 |
阴影 Y 偏移 |
应用阴影 Y 偏移 |
|
string, |
|
阴影颜色 |
最终颜色非空且可解析时应用 |
|
integer, |
内建默认 theme 为 |
整体透明度 |
字段显式存在时覆盖 theme;最终无值时 backend 用 |
|
number px 或 |
内建默认 theme 为 |
line 控件线宽 |
应用线宽 |
|
integer, |
内建默认 theme 为 |
image 绘制透明度 |
字段显式存在时覆盖 theme;最终无值时 backend 用 |
|
string, |
|
image 绘制重着色 |
空字符串关闭 style 层重着色 |
|
integer, |
|
image 重着色混合强度 |
仅在 |
|
number px 或 |
backend 默认 |
arc 弧线宽度 |
可写在 |
|
integer, |
|
arc 弧线透明度 |
可写在 |
|
integer, |
|
arc 渐变分段数量 |
段数越大越平滑,绘制成本也越高 |
|
boolean |
backend 默认 |
arc 端点圆角 |
映射到 LVGL arc rounded |
|
boolean |
backend 默认 |
是否按圆角裁剪子内容 |
映射到 LVGL clip corner;通常配合 |
stateStyles
节点可通过 stateStyles 为单个交互状态提供局部 style 覆盖。stateStyles 的字段规则与 style 相同,
但不支持 font / fontSize / imageFontSize,避免状态切换时重新创建字体缓存。
{
"type": "button",
"id": "open",
"styleRefs": ["app.card"],
"stateStyles": {
"pressed": {"bgColor": "#e2e8f0"},
"disabled": {"opacity": 120},
"checked": {"borderColor": "#2563eb", "borderWidth": "2dp"}
}
}
支持的状态名:
状态 |
含义 |
|---|---|
|
正在按下 |
|
已选中;例如 switch / checkbox 或手动设置 checked state 的控件 |
|
获得焦点 |
|
键盘/方向键焦点 |
|
编辑状态 |
|
指针悬停 |
|
滚动中 |
|
禁用状态 |
|
预留用户状态 |
合成规则:
base
style的合成顺序不变。每个 state 的覆盖样式按同样层级合成:内建 theme、当前 theme、
styleRefs、节点自身stateStyles。state style 只写显式字段;未写字段继承普通状态的最终样式。
只支持单一状态选择器,不支持
pressed+checked这种组合状态。binding / event effect 可写入
stateStyles.<state>.<styleField>,例如stateStyles.pressed.bgColor。
partStyles
partStyles 用于给控件内部部件设置样式。现有 style 始终表示 main 部分;partStyles
表示同一个 view 的其他部件。当前支持:
Part |
常见控件 |
含义 |
|---|---|---|
|
|
已填充进度、slider 选中轨道、arc 指示弧 |
|
|
拖动手柄 |
写法支持直接 style shorthand,也支持 style + stateStyles:
{
"type": "slider",
"id": "brightness",
"partStyles": {
"indicator": {
"bgColor": "#2563eb",
"bgGradientColor": "#38bdf8",
"bgGradientDirection": "horizontal"
},
"knob": {
"style": {
"bgColor": "#ffffff",
"radius": "14dp"
},
"stateStyles": {
"pressed": {"bgColor": "#e0f2fe"}
}
}
}
}
合成规则:
style仍按main部分合成。每个 part 的 style 按相同层级合成:内建 theme、当前 theme、
styleRefs、节点自身partStyles。partStyles.<part>.stateStyles同样支持 state 覆盖。partStyles不支持font/fontSize/imageFontSize。binding / event effect 可写入
partStyles.indicator.bgGradientColor、partStyles.knob.stateStyles.pressed.bgColor等字段。
Range 渐变
progressBar 和 slider 的 partStyles.indicator 使用 LVGL 背景渐变,适合横向/纵向进度色:
"partStyles": {
"indicator": {
"bgColor": "#22c55e",
"bgGradientColor": "#3b82f6",
"bgGradientDirection": "horizontal"
}
}
arc 没有原生 arc gradient;LVGL backend 在 partStyles.indicator.arcGradientColor 存在时使用分段绘制近似:
"partStyles": {
"indicator": {
"arcColor": "#22c55e",
"arcGradientColor": "#3b82f6",
"arcWidth": "10dp",
"arcRounded": true,
"arcGradientSegments": 48
}
}
主题默认样式层
Runtime 在解析节点最终 style 前总会先应用一份内建默认 theme。若 Runtime 已额外加载全局 theme,并通过 set_theme(...) 选中当前主题,还会继续自动应用:
styles.allstyles.<节点 type>
示例:
{
"id": "dark",
"styles": {
"all": {
"bgColor": "#020617"
},
"label": {
"textColor": "#f8fafc"
}
}
}
若某个 label 节点又显式写了:
"style": {
"textColor": "#ef4444"
}
则最终 textColor 以节点显式值为准。
颜色字段接受两种写法:字面量 #RRGGBB,或颜色引用 ${color.<path>}``(从当前 theme 的 ``colors 解析)。
${color.*} 仅可用于颜色类 style 字段,例如 bgColor、textColor、borderColor、lineColor、arcColor、
shadowColor、imageRecolor 及其对应的 stateStyles / partStyles 字段。空字符串表示不设置该颜色;
非法颜色或其他 CSS 写法会在 document validator 阶段报错,不会进入 backend 应用流程。
字体与字号
font 必须使用资源引用:
{
"style": {
"font": "${font.title}",
"fontSize": "${constant.metrics.titleFont}",
"textColor": "${constant.colors.primaryText}"
}
}
资源引用规则:
font: "${font.title}"在 parser 中保留为字体资源引用,不会按普通常量替换。runtime 会合并 JSON 字体资源和 backend 动态字体资源。
若 JSON 和 backend 都提供同名字体,backend 动态资源优先。
不支持
font: "title"、${font:title}或把字体文件路径直接写到style.font。
字号规则:
fontSize推荐使用"Nsp"或${constant.*}中解析出的"Nsp"。sp公式为round(N * Environment.density * Environment.font_scale)。裸数字表示已经换算好的 px,不受
font_scale影响。未显式设置
fontSize时,内建默认 theme 提供16。若需要应用字体但最终
fontSize为0,backend 字体选择逻辑会使用默认字号16。imageFontSize推荐用于style.font指向kind=imageFont的节点,例如 label 内联图标。 它按sp转 px 后只选择 imageFont 的 glyph 图片尺寸;普通字符仍由fontSize控制。
后端字体优先级:
ResolvedFontSpec.native_fonts中最接近请求字号的 native font。JSON/backend 字体资源的
primary_src,并按 fallback 链创建 FreeType 字体。内置 Montserrat 字体;FreeType 不可用或文件不可用时也会回退到内置字体。
尺寸与间距
尺寸类 style 字段接受裸数字 px 或 "Ndp":
{
"style": {
"padding": "${constant.metrics.sectionPadding}",
"borderWidth": "1dp",
"radius": "${constant.radii.card}",
"shadowWidth": "8dp",
"shadowOffsetY": "2dp"
}
}
当前规则:
每一层 style 只有字段显式存在时才覆盖前序层;节点省略字段会继承内建 theme 或当前 Runtime theme 的最终合并值。
内建默认 theme 的
all层提供borderWidth/radius/padding/margin/shadowWidth/lineWidth等数值 baseline。padding和分方向padding*同时存在时,backend 以最终padding作为回退值,再由分方向字段逐项覆盖。margin和分方向margin*同理。颜色和字体 id 仍保留“空字符串表示不设置具体资源/颜色”的语义。
透明度
{
"style": {
"opacity": 220,
"imageOpacity": 180,
"imageRecolor": "#0f172a",
"imageRecolorOpacity": 255
}
}
说明:
opacity影响对象整体透明度。imageOpacity影响 image 绘制透明度。imageRecolor/imageRecolorOpacity影响 image 绘制颜色,可放在 theme style 中供 icon 统一适配主题。内建默认 theme 的默认值都是
255,表示完全不透明;外部 theme 或节点显式字段可覆盖该值。当前 parser 只要求 integer,validator 会进一步限制为
0..255;超出范围会导致 document 校验失败。
示例
下面示例展示典型的样式与资源引用写法,资源引用保持严格 namespace:
{
"type": "container",
"id": "content",
"style": {
"padding": "${constant.metrics.sectionPadding}",
"bgColor": "${constant.colors.cardBg}",
"borderColor": "${constant.colors.border}",
"borderWidth": "1dp",
"radius": "${constant.radii.card}"
},
"children": [
{
"type": "label",
"id": "title",
"labelProps": {
"text": "Controls Gallery"
},
"style": {
"font": "${font.title}",
"fontSize": "${constant.metrics.titleFont}",
"textColor": "${constant.colors.primaryText}"
}
},
{
"type": "line",
"id": "line",
"style": {
"lineColor": "${constant.colors.accent}",
"lineWidth": "3dp"
}
}
]
}