本文围绕 Jetpack Compose 桌面应用中「外壳背景不等于主题背景」这一细节展开,讨论颜色分层、装饰接缝与代码一致性。
用途:面向使用 Compose 构建桌面外壳(窗口色 + 圆角浮动面板)的开发者,说明为何渐变、遮罩和淡出的尾部不能继续指向 colorScheme.background,并给出修复与验证思路。
主要能力与观点:
- 外壳背景通常由窗口色和面板色组成,面板色并非 colorScheme.background,而是向中间色退一档,以形成凸起感。
- 当装饰的尾部收敛到 colorScheme.background 时,由于背后不再绘制该颜色,会出现一条清晰的横向接缝;不会报错、不会记录日志,在无外壳的平台上仍显示正常。
- 正确做法只有两种:让尾部对准外壳实际绘制的颜色,或自行绘制不透明底色并对准该底色。不能一边让面板透出、一边让尾部对准主题背景。
- 建议把解析后的值统一命名为 pageBackground,并通过一个函数或 CompositionLocal 集中提供,避免多处复制导致漂移。
- 明暗判断必须在所有位置使用同一表达式(文中示例为 background.luminance() > 0.5f),且必须在主题内部解析,不能在主题之外计算。
- 装饰应使用 matchParentSize() 随内容尺寸变化,而不是固定高度;固定高度只在装饰本身确实固定高度时才合适。
- 需要同时考虑窗口色、面板色、主题背景色,以及页面自绘的不透明底色,共三到四种颜色。
- 窗口色与面板色应成对解析,否则在某一主题下会落到同一侧,导致面板融入窗口。
- 应用栏默认容器色会覆盖承载颜色的顶部区域,建议使用透明容器并让应用栏做磨砂效果。
- 添加外壳会影响每个屏幕,但外壳提交的 diff 不会体现这一点;上线前应搜索所有收敛到主题背景的装饰并逐一处理。
使用方式:文中提供了三条 grep 验证命令,分别检查 pageBackground 的副本数量与一致性、装饰尾部收敛目标,以及装饰是否使用 matchParentSize() 而非固定高度;并建议在窄窗口与宽窗口下分别目视检查装饰结束边界,还可临时把面板色改为醒目颜色以暴露接缝。
适用场景:Compose 桌面外壳、多主题(明/暗/强制暗)应用、带渐变或遮罩装饰的界面。
限制:本文为经验性技术笔记,未提供完整项目、依赖版本或可直接运行的示例工程;具体 API 行为以所用 Compose 版本为准。