AutoJs6 icon indicating copy to clipboard operation
AutoJs6 copied to clipboard

悬浮窗控制台透明度有点问题

Open wengzhenquan opened this issue 1 month ago • 7 comments

当我用build先设置过。 然后再修改,发现透明度不一致。

console.build({
                size: [0.96, 0.3],
                position: [0.02, 0.02],
                title: '会装逼的控制台',
                titleTextSize: 18,
                titleTextColor: 'green',
                titleIconsTint: 'yellow',
                titleBackgroundAlpha: 0.8,
                titleBackgroundColor: 'dark-blue',
                contentTextSize: 15,
                contentBackgroundAlpha: 0.7,
                contentBackgroundColor: colors.BLACK,
                touchable: true,
                exitOnClose: false,
            });

             if (满足某种条件重新设置透明度,比如从配置里加载){
              console.setContentBackgroundAlpha(value1);
               console.setTitleBackgroundAlpha(value2);
              }

如果条件里的值跟build里的值一样,理论上效果也是一样的。 但实际效果却并非如此。 到底是什么原因呢? 即便console.resetBackgroundAlpha()后重新设置也不行。

难道变成0.7x0.7, 0.8x0.8了吗

wengzhenquan avatar Oct 30 '25 04:10 wengzhenquan

经过测试, 应该是 contentBackgroundAlpha 与 titleBackgroundAlpha 两个属性在 build 选项参数中没有生效. 这是 console.build 方法的 bug. 我会抽空检查一下源码以排查问题.

并不是多次设置透明度会叠加, 一个简单的验证方法:

console.build({
    size: [0.96, 0.3],
    position: [0.02, 0.02],
    title: '会装逼的控制台',
    titleTextSize: 18,
    titleTextColor: 'green',
    titleIconsTint: 'yellow',
    titleBackgroundAlpha: 0.8,
    titleBackgroundColor: 'dark-blue',
    contentTextSize: 15,
    contentBackgroundAlpha: 0.7,
    contentBackgroundColor: colors.BLACK,
    touchable: true,
    exitOnClose: false,
});
let max = 3;
while (max--) {
    console.setContentBackgroundAlpha(0.7);
    console.setTitleBackgroundAlpha(0.8);
}

console.show();

即使 max 设置为 10, 透明度也依然保持不变.

我会在问题排查清楚后给出具体的原因.

Sent from my XQ-DQ72 using FastHub

SuperMonster003 avatar Oct 30 '25 04:10 SuperMonster003

去掉 console.setContentBackgroundAlpha(0.7); console.setTitleBackgroundAlpha(0.8);

只保留build中的透明度,试试。

wengzhenquan avatar Oct 30 '25 07:10 wengzhenquan

奇怪了。单独demo测试,build确实没有生效。 但我的脚本里面,却发现透明度有变化

wengzhenquan avatar Oct 30 '25 08:10 wengzhenquan

我知道了,build应该是默认值0.6,0.8生效的

wengzhenquan avatar Oct 30 '25 08:10 wengzhenquan

setXxxBackgroundAlpha
setXxxBackgroundTint
setXxxBackgroundColor

以上三种设置背景透明度/着色/基色的方法, 在 console 模块中有两组:

setTitleBackgroundAlpha
setTitleBackgroundTint
setTitleBackgroundColor

setContentBackgroundAlpha
setContentBackgroundTint
setContentBackgroundColor

为方便起见, 仅以 setTitleBackgroundXxx 为例讨论后续内容.

通常情况下, 对于 ARGB 颜色, AARRGGBB 中的 AA 由 setTitleBackgroundAlpha 控制, RRGGBB 由 setTitleBackgroundTint 控制, AARRGGBB 由 setTitleBackgroundColor 进行控制. 后者会覆盖前者:

setTitleBackgroundColor('red');
setTitleBackgroundTint('green');

上述代码中, tint 会覆盖 color, 最终色值为绿色. 如果调换两行代码, color 会覆盖 tint, 最终色值为红色.

下面是一个容易出现问题的地方, 即 color 的透明度隐含问题:

setTitleBackgroundColor('red');
setTitleBackgroundAlpha(0.5); // 转换为 Unit8, 将得到 128

很明显, 最终色值是一个半透明红色. 如果调换两行代码呢... 结果是不透明红色. 这是因为 'red' 隐含了透明度为 255 的条件, 转换为 Full ColorHex, 结果为 '#FFFF0000', 因此前面两位 FF 会作为 255 透明度覆盖掉 setTitleBackgroundAlpha(0.5) 的设置.

在 console.show() 之前, 不论是 build 还是 setXxx, 都不会直接对控制台浮动窗口进行设置, 而是将预备变量进行设置, 在 show() 调用时读取这些预备变量再进行设置视图渲染及窗口绘制.

AutoJs6 6.6.4 的设置缺陷, 导致 color 会覆盖 alpha 以及 alpha 可能无法正常覆盖 color 的问题.

一个可行的修复思路是将三者 ("color/alpha/tint", 即 "基色/透明度/色调") 拆分成独立的内部状态, 并在读取时统一 "校准合成":

inner class Configurator {

    ... ...
    
    @Volatile
    private var internalContentBackgroundColor: Int? = null
    @Volatile
    private var internalContentBackgroundAlpha: Int? = null
    @Volatile
    private var internalContentBackgroundTint: Int? = null
    
    val contentBackgroundColor: Int
        get() = (internalContentBackgroundColor ?: context.getColor(R.color.floating_console_content_bg))
            .calibrateWith(internalContentBackgroundAlpha, internalContentBackgroundTint)
    
    private fun Int.calibrateWith(alpha: Int?, tint: Int?): Int {
        var result = this
        alpha?.let { desired -> result = Color.argb(desired, result.red, result.green, result.blue) }
        tint?.let { desired -> result = Color.argb(result.alpha, desired.red, desired.green, desired.blue) }
        return result
    }

    ... ...
    
}

未来 AutoJs6 将修复上述问题.

目前的解决方案 (脚本层面) 是使用 tint 替代 color, 因为 tint 不涉及 alpha, 仅包含 RRGGBB 数据.

SuperMonster003 avatar Nov 01 '25 06:11 SuperMonster003

在 console.show() 之前, 不论是 build 还是 setXxx, 都不会直接对控制台浮动窗口进行设置, 而是将预备变量进行设置, 在 show() 调用时读取这些预备变量再进行设置视图渲染及窗口绘制.

那么,修改呢? 假如已经设置并且执行show() ,然后动态修改透明度,还需要show() 应用吗?

wengzhenquan avatar Nov 01 '25 06:11 wengzhenquan

上述疑问:

假如已经设置并且执行 show() , 然后动态修改透明度, 还需要 show() 应用吗?

理论上是不需要重新 show() 的. console.setXxx 应该是立即生效的. 但目前 AutoJs6 对于 console 相关的 Setter API 的实现和处理缺乏足够的合理性. 同时我们之前讨论的 "color/alpha/tint" (即 "基色/透明度/色调") 的设计也是不合理的. 未来我打算将上述 Setter 方法仔细检查其内部功能实现的合理性, 并重新设计 "color/alpha/tint" 的相关实现, 使其更符合安卓官方的设计规范. 顺便也打算将 console 的内部实现无锁化, 这样可以大幅度提升 console 浮动窗口的显示效率和设置参数生效的成功率.

SuperMonster003 avatar Nov 10 '25 07:11 SuperMonster003