fix: 主题模板真正应用到设置页 UI

之前主题模板只影响了 getPanelBgColorInt/getPanelTextColorInt,
但设置页 UI(buildSettingsGroupPanelView)的颜色全部来自
getAnimalIslandTheme() 硬编码,完全不经过模板逻辑。

修复:
1. buildSettingsGroupPanelView 开头判断是否选了非 system 模板,
   若是则根据模板的 dayBg/dayText/nightBg/nightText 自动生成
   一套兼容 T 结构的配色,覆盖 Animal Island 的 T 对象
2. 模板值从 pendingUserCfg 读取(预览态)
3. setPendingValue 中当 key=THEME_TEMPLATE 时,通过
   replaceToolAppPage('settings_group') 重建整个设置页 UI,
   使模板切换立即生效
This commit is contained in:
7015725
2026-05-15 02:11:38 +08:00
parent 1c802f6948
commit cb01591369
4 changed files with 74 additions and 6 deletions

View File

@@ -154,6 +154,23 @@ FloatBallAppWM.prototype.setPendingValue = function(k, v) {
this.state.pendingUserCfg[k] = v;
this.state.pendingDirty = true;
if (this.state.previewMode) {
// 主题模板切换需要重建整个设置页 UI配色来自 buildSettingsGroupPanelView
if (String(k) === "THEME_TEMPLATE") {
try {
if (this.state.toolAppActive && this.replaceToolAppPage) {
this.replaceToolAppPage("settings_group");
} else {
// 非 ToolApp 模式:销毁旧设置面板重建
if (this.state.settingsPanel) {
this.safeRemoveView(this.state.settingsPanel, "settingsPanel");
this.state.settingsPanel = null;
this.state.settingsPanelLp = null;
this.state.addedSettings = false;
}
this.replaceToolAppPage("settings_group");
}
} catch(eReb) { safeLog(null, 'e', "catch " + String(eReb)); }
}
this.refreshPreview(k);
}
};

View File

@@ -256,6 +256,57 @@ FloatBallAppWM.prototype.buildSettingsGroupPanelView = function() {
var isDark = this.isDarkTheme();
var C = this.ui.colors;
var T = this.getAnimalIslandTheme();
// 如果用户选择了非 system 的主题模板,根据模板颜色构造设置页配色替代 Animal Island
// 优先从 pendingUserCfg 读模板值(预览态),其次从 this.config
var cfgTpl = this.state.pendingUserCfg ? this.state.pendingUserCfg : this.config;
var tpl = String(cfgTpl.THEME_TEMPLATE || "system");
if (tpl !== "system") {
try {
var tplColors = this.getThemeTemplate(tpl);
var Color = android.graphics.Color;
var dayBg = tplColors.dayBg ? android.graphics.Color.parseColor(tplColors.dayBg) : null;
var dayText = tplColors.dayText ? android.graphics.Color.parseColor(tplColors.dayText) : null;
var nightBg = tplColors.nightBg ? android.graphics.Color.parseColor(tplColors.nightBg) : null;
var nightText = tplColors.nightText ? android.graphics.Color.parseColor(tplColors.nightText) : null;
var bg = isDark ? (nightBg || T.bg) : (dayBg || T.bg);
var txt = isDark ? (nightText || T.text) : (dayText || T.text);
// 根据主背景色推导辅助色:用调亮/调暗/混合方式生成 T 结构的其他字段
var r = Color.red(bg), g = Color.green(bg), b = Color.blue(bg);
var lum = (r*0.299 + g*0.587 + b*0.114) / 255.0;
var subTxt = isDark ? Color.rgb(
Math.min(255, Color.red(txt) + 40),
Math.min(255, Color.green(txt) + 40),
Math.min(255, Color.blue(txt) + 40)
) : Color.rgb(
Math.max(0, Color.red(txt) - 40),
Math.max(0, Color.green(txt) - 40),
Math.max(0, Color.blue(txt) - 40)
);
var cardBg = isDark ? Color.rgb(
Math.min(255, r + 25), Math.min(255, g + 25), Math.min(255, b + 25)
) : Color.rgb(
Math.max(0, r - 20), Math.max(0, g - 20), Math.max(0, b - 20)
);
var card2 = isDark ? Color.rgb(
Math.max(0, r + 40), Math.max(0, g + 40), Math.max(0, b + 40)
) : Color.rgb(
Math.min(255, r - 30), Math.min(255, g - 30), Math.min(255, b - 30)
);
T.bg = bg;
T.card = cardBg;
T.card2 = card2;
T.text = txt;
T.sub = subTxt;
T.primary = this.ui.colors.primary;
T.primaryDeep = this.ui.colors.primary;
T.primarySoft = isDark ? this.withAlpha(this.ui.colors.primary, 0.20) : this.withAlpha(this.ui.colors.primary, 0.12);
T.brown = txt;
T.stroke = isDark ? this.withAlpha(txt, 0.25) : this.withAlpha(txt, 0.18);
T.onPrimary = this.ui.colors._monetOnPrimary || (isDark ? Color.parseColor("#062E6F") : Color.WHITE);
} catch(eTpl) { safeLog(null, 'e', "catch " + String(eTpl)); }
}
var bgColor = T.bg;
var cardColor = T.card;
var textColor = T.text;