问题
I am using setColorFilter
to set the color filter of ONE of my button. This has been working perfectly until the Android 5.0 Lollipop update. Now, the color filter seems to leak onto my other buttons, even when I close the activity and reopen (it resets if I close the app and reopen).
My styles.xml (v21): (same as older except here its parent is Material, before it was 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>
My styles.xml (for all versions):
<style name="StandardButton" parent="android:style/Widget.Button">
<item name="android:background">@android:drawable/btn_default</item>
</style>
My Button:
<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" />
My code:
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);
The color:
<color name="light_green">#5CD65C</color>
The result:
I open the app, then the game activity and all the buttons are displaying correctly. I press the button to set the color filter, go back to the main Menu and reopen the game activity and now all buttons are green.
Any ideas?
回答1:
The problem is that the background Drawable
is reused across many Views. To ensure the Drawable
is not shared between multiple Views you should use the mutate
method.
See: mutate()
Example code:
Drawable background = mainMenuButton.getBackground();
background.mutate();
background.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY));
mainMenuButton.setBackground(background);
回答2:
The instance of the drawable is shared across all your buttons, so setting a colorfilter changes all of them (you don't see the changes immediatly because the buttons are not invalidating immediatly).
Try to load the drawable manually (BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_default, null)
) and then set it as the button background.
回答3:
OP here. Thank you for your suggestions. Using the following code fixed the problem.
Setting the filter
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);
The other buttons did not become green.
Clearing the filter
What happened next was, that it seemed that Android (partly) ignored my call to clear the color filter (which happens later on in the code). "Partly", because it was green, but when I pressed it, it became yellow (which is btn_default behavior as opposed to dark green with the filter). To fix this, I had to change my function call order to the following:
mainMenuButton.setVisibility(View.VISIBLE)
mainMenuButton.getBackground().clearColorFilter();
mainMenuButton.invalidate();
NOTE: This however inversed the behavior of the button. When I press (and hold) on the button, it seems to still have the green color filter behavior on it and becomes dark green. When I release it returns to being grey as per btn_default. Any suggestions on this?
I hope this at least somehow helps someone else with this strange problem, which for me only occured on Android 5.0 Lollipop API level 21. (I have tested API 8, 9, 12, 13, 16, 17, 18 and 19 where this problem did not occur. Also it doesn't seem to be ART with its AOT compilation as I expected, since enabling ART on an Android 4.4.4 device did not cause this problem.) Strangely, mutate()
did not work either, as I would have expected.
来源:https://stackoverflow.com/questions/27015811/android-5-0-lollipop-setcolorfilter-leaks-onto-other-buttons