Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 5.0 Lollipop: setColorFilter "leaks" onto other buttons

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?

like image 805
Johis Avatar asked Nov 19 '14 11:11

Johis


2 Answers

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);
like image 86
Rolf ツ Avatar answered Sep 23 '22 19:09

Rolf ツ


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.

like image 34
Spotlight Avatar answered Sep 26 '22 19:09

Spotlight