From d9ca9dbe31b5fbb22b42fd9c5153783a0162c96f Mon Sep 17 00:00:00 2001 From: laoyang Date: Thu, 5 Nov 2026 20:25:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8B=E6=8B=89=E6=A1=86=E4=B8=8E=E7=BD=91?= =?UTF-8?q?=E9=A1=B5=E7=AB=AF=E5=AF=B9=E9=BD=90=EF=BC=88=E7=85=A7=20FeedLi?= =?UTF-8?q?te=20=E9=82=A3=E5=A5=97=E8=A7=82=E6=84=9F=EF=BC=89(#86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户 2026-11-05:「好了,鸿蒙端也用类似的方式调,效果让它保持一致。」 端上**不需要像网页那样手写浮层** —— 网页端必须自绘是因为 「原生 select 的展开列表由浏览器绘制,CSS 改不动」; ArkUI 的 Select 本身就是自绘的、选项列表也归框架管。 ⇒ 把对应属性都设上就等价了: 网页端 ArkUI Select ────────────────────────────────────────────────────── 按钮 40 高 / 圆角 / 细边框 height(40) + borderRadius + border 箭头打开转 180° 框架内置(自带动画) 悬停 tint-1 不支持(触屏没有 hover)→ 用打开态代替 选中项底 tint-2 selectedOptionBgColor(fbMixWhite(accent,0.80)) 选中项文字 主题色 selectedOptionFontColor(accent) 选中项右侧对勾 showDefaultSelectedIcon(true) 浮层白底 + 细边框 menuBackgroundColor(White) + border 浮层与按钮同宽 optionWidth(OptionWidthMode.FIT_TRIGGER) 未选值次要色 fontColor(有值 ? accent : Faint) ① Theme 新增 fbMixWhite(hex, ratio) 与网页端 fb_color_tint() **同算法同比例**(混 91/80/72% 白)。 ⚠️ 为什么不用现成的 fbAlpha():那是「原色 + 透明度」, 会透出父容器底色 —— 下拉浮层背景不确定,那样会时深时浅; 这里是实色混合,颜色确定。 ⚠️ 实测 16 组(4 个主题色 × 4 档比例)与 PHP 输出逐个比对,全部一致。 ② 边框单独用一档 按钮边框 fbMixWhite(accent, 0.62) —— 比 tint-3 再深一点, 否则在 tint-1 的浅底上几乎看不见边界。 ③ 修一个类型坑 本来写了个 pickFontColor(): string 返回 accent / FbColors.muted, 但 FbColors.muted 是 Resource($r(...)),返回 string | Resource 会让 fontColor() 报「Type 'string | Resource' is not assignable to 'string'」。 ⇒ 改成内联三元,且未选用 FbColors.faint(那个是 string 常量)。 编译通过,已装真机。 --- entry/src/main/ets/common/Theme.ets | 55 +++++++++++++++++ entry/src/main/ets/components/FbTaskPanel.ets | 60 +++++++++++++------ 2 files changed, 97 insertions(+), 18 deletions(-) diff --git a/entry/src/main/ets/common/Theme.ets b/entry/src/main/ets/common/Theme.ets index d91c219..15639eb 100644 --- a/entry/src/main/ets/common/Theme.ets +++ b/entry/src/main/ets/common/Theme.ets @@ -386,6 +386,61 @@ function fbIconOf(name: string): Resource { * @param hex 六位十六进制(`#RRGGBB`;也容忍八位,会先截成前六位) * @param alpha 0~1(0.4 = 40% 不透明) */ +/** + * 把主题色往白色方向混,得到一档浅色。 + * + * 🔴 #86(用户 2026-11-05):「鸿蒙端也用类似的方式调,效果让它保持一致。」 + * + * 与网页端 `fb_color_tint()`(app/helpers.php)**必须是同一个算法**, + * 否则同一条任务在两端的下拉项颜色不一样 —— 那就白"保持一致"了。 + * + * 网页端的三档: + * tint-1(混 91% 白)→ 悬停 / 打开态底 + * tint-2(混 80% 白)→ 选中项底 + * tint-3(混 72% 白)→ 选中项悬停 + * + * ⚠️ 与 `fbAlpha()` 的区别:那个是"原色 + 透明度"(透出背景色,会受 + * 父容器底色影响);这个是"实色混合"(不透明,颜色确定)。 + * 下拉项底色必须用实色 —— 用透明度的话叠在白色面板上还行, + * 但它自己是浮层,背景不确定,会时深时浅。 + * + * @param hex 六位十六进制(`#RRGGBB`) + * @param ratio 往白色混多少(0.91 = 91% 白 + 9% 原色) + */ +export function fbMixWhite(hex: string, ratio: number): string { + let base: string = hex.trim(); + if (base.startsWith('#')) { + base = base.substring(1); + } + if (base.length > 6) { + base = base.substring(base.length - 6); + } + if (base.length !== 6) { + return hex; // 不是 6 位 hex(如 rgba())→ 原样返回,调用方自己兜底 + } + const r: number = parseInt(base.substring(0, 2), 16); + const g: number = parseInt(base.substring(2, 4), 16); + const b: number = parseInt(base.substring(4, 6), 16); + if (isNaN(r) || isNaN(g) || isNaN(b)) { + return hex; + } + let q: number = ratio; + if (q < 0) { + q = 0; + } + if (q > 1) { + q = 1; + } + const nr: number = Math.round(r + (255 - r) * q); + const ng: number = Math.round(g + (255 - g) * q); + const nb: number = Math.round(b + (255 - b) * q); + const h2 = (v: number): string => { + const s2: string = v.toString(16).toUpperCase(); + return s2.length < 2 ? '0' + s2 : s2; + }; + return '#' + h2(nr) + h2(ng) + h2(nb); +} + export function fbAlpha(hex: string, alpha: number): string { let base: string = hex.trim(); if (base.startsWith('#')) { diff --git a/entry/src/main/ets/components/FbTaskPanel.ets b/entry/src/main/ets/components/FbTaskPanel.ets index 91898d3..935846d 100644 --- a/entry/src/main/ets/components/FbTaskPanel.ets +++ b/entry/src/main/ets/components/FbTaskPanel.ets @@ -29,7 +29,7 @@ * 挤出屏幕(本项目 2026-10-20 真机事故,见 pitfalls)。 */ -import { FbColors, FbMetric, FB_MASK, fbAlpha, fbTint } from '../common/Theme'; +import { FbColors, FbMetric, FB_MASK, fbAlpha, fbTint, fbMixWhite } from '../common/Theme'; import { FbBoardOpt, FbCatOpt, FbTaskAttach, FbTaskComment, FbTaskDetail, FbTaskItem, FbTaskKid, FbTaskShare, } from '../model/Types'; @@ -1472,32 +1472,51 @@ export struct FbTaskPanel { .backgroundColor(FbColors.inputBg) .borderRadius(FbMetric.radiusS) } else { - /* 🔴 #84(用户 2026-11-05): - 「分类弹出来的框太窄了,应该和输入框一样宽。」 - 「颜色也不对。它的颜色应该是主题色:里面的文字颜色是主题色, - 背景色是比主题色浅一点的那个主题色。」 + /* 🔴🔴 #86(用户 2026-11-05):「鸿蒙端也用类似的方式调, + 效果让它保持一致。」 - · `width('100%')` 管的是**控件本身**;弹出来的下拉菜单 - 还有自己的宽度(`optionWidth`),不给就按内容撑 ⇒ 很窄。 - 用 `optionWidth(OptionWidthMode.FIT_TRIGGER)` 让它跟触发器同宽。 - · 文字 `this.accent`、底色 `fbAlpha(this.accent, 0.10)` - —— 与面板里「+ 添加附件」那颗胶囊同一套(主题色 + 淡底), - 这样"可操作"的控件在全面板观感一致。 */ + 网页端照 FeedLite 做成"自绘按钮 + 浮层列表"(原生