我正在使用setColorFilter
来设置我的一个按钮的颜色过滤器。这一直在Android 5.0 Lollipop更新之前完美运行。现在,滤色器似乎泄漏到我的其他按钮上,即使我关闭活动并重新打开(如果我关闭应用程序并重新打开它会重置)。
我的styles.xml(v21):(与旧版本相同,除非此处其父级为“材质”,否则为“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>
结果:
我打开应用程序,然后游戏活动和所有按钮都正确显示。我按下按钮设置彩色滤镜,返回主菜单并重新打开游戏活动,现在所有按钮都是绿色。
有什么想法吗?
答案 0 :(得分:20)
问题是后台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);
答案 1 :(得分:1)
drawable的实例在所有按钮中共享,因此设置colorfilter会更改所有按钮(您不会立即看到更改,因为按钮不会立即失效)。
尝试手动加载drawable(BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_default, null)
),然后将其设置为按钮背景。
答案 2 :(得分:1)
OP在这里。谢谢你的建议。使用以下代码修复了该问题。
设置过滤器
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编译似乎并不像我预期的那样,因为在Android 4.4.4设备上启用ART不会导致这个问题。)奇怪的是,mutate()
没有正如我所预料的那样工作。