【问题标题】:Android 5.0 Lollipop: setColorFilter "leaks" onto other buttonsAndroid 5.0 Lollipop:setColorFilter“泄漏”到其他按钮上
【发布时间】:2014-11-19 11:32:32
【问题描述】:

我正在使用setColorFilter 设置我的按钮之一的颜色过滤器。在 Android 5.0 Lollipop 更新之前,它一直运行良好。现在,即使我关闭活动并重新打开(如果我关闭应用程序并重新打开,它也会重置),颜色过滤器似乎泄漏到我的其他按钮上。

我的 styles.xml (v21):(与旧版本相同,除了这里它的父级是 Material,在它是 Holo 之前)

<style name="Theme.FullScreen" parent="@android:style/Theme.Material.Light.NoActionBar.Fullscreen">
    <item name="android:buttonStyle">@style/StandardButton</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

我的 styles.xml(适用于所有版本):

<style name="StandardButton" parent="android:style/Widget.Button">
    <item name="android:background">@android:drawable/btn_default</item>
</style>

我的按钮:

<Button
    android:id="@+id/mainMenuButton"              
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="mainMenu"
    android:text="@string/button_mainMenu"
    android:visibility="gone" />

我的代码:

Button mainMenuButton = (Button) findViewById(R.id.mainMenuButton);
mainMenuButton.getBackground().setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY));
mainMenuButton.setVisibility(View.VISIBLE);

颜色:

<color name="light_green">#5CD65C</color>

结果:

我打开应用程序,然后游戏活动和所有按钮都正确显示。我按下按钮设置颜色过滤器,返回主菜单并重新打开游戏活动,现在所有按钮都是绿色的。

有什么想法吗?

【问题讨论】:

    标签: android android-layout android-5.0-lollipop android-styles


    【解决方案1】:

    问题是背景Drawable 在许多视图中重复使用。为确保Drawable 不会在多个视图之间共享,您应该使用mutate 方法。

    见:mutate()

    示例代码:

    Drawable background = mainMenuButton.getBackground();
    background.mutate();
    background.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY));
    mainMenuButton.setBackground(background);
    

    【讨论】:

    • 当我读到你的回答时,我高兴得跳了起来,因为它看起来如此简单和直观(我以前从未听说过mutate())。我赶到我的项目并实施了您的解决方案,遗憾的是,它不起作用。我所有的按钮仍然变成绿色。我什至试过:background = background.mutate(); 然后在上面设置过滤器,但按钮仍然变绿。我不知道还有什么可以尝试的(除了在所有其他按钮上调用clearFilter(),这可行,但代码真的很难看)。
    【解决方案2】:

    drawable 的实例在所有按钮之间共享,因此设置颜色过滤器会更改所有按钮(您不会立即看到更改,因为按钮不会立即失效)。

    尝试手动加载drawable(BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_default, null)),然后将其设置为按钮背景。

    【讨论】:

      【解决方案3】:

      在这里。谢谢你的建议。使用以下代码解决了该问题。

      设置过滤器

      Drawable background = getResources().getDrawable(android.R.drawable.btn_default);
      background.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY));
      mainMenuButton.setBackground(background); // Use setBackgroundDrawable for API<16
      mainMenuButton.setVisibility(View.VISIBLE);
      

      其他按钮没有变成绿色。

      清除过滤器

      接下来发生的事情是,Android 似乎(部分)忽略了我清除颜色过滤器的调用(稍后在代码中发生)。 “部分”,因为它是绿色的,但是当我按下它时,它变成了黄色(这是 btn_default 行为,而不是过滤器的深绿色)。为了解决这个问题,我不得不将我的函数调用顺序更改为以下:

      mainMenuButton.setVisibility(View.VISIBLE)
      mainMenuButton.getBackground().clearColorFilter();
      mainMenuButton.invalidate();
      

      注意:然而,这与按钮的行为相反。当我按下(并按住)按钮时,它似乎仍然具有绿色滤光片行为并变成深绿色。当我释放它时,它会根据 btn_default 恢复为灰色。对此有何建议?

      我希望这至少能以某种方式帮助其他人解决这个奇怪的问题,对我来说,这个问题只发生在 Android 5.0 Lollipop API 级别 21 上。(我已经测试了 API 8、9、12、13、16、17、18 和 19没有出现这个问题的地方。而且它似乎不像我预期的那样是带有 AOT 编译的 ART,因为在 Android 4.4.4 设备上启用 ART 不会导致这个问题。)奇怪的是,mutate() 也不起作用,正如我所预料的那样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-05
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        相关资源
        最近更新 更多