Android 5.0 Lollipop: setColorFilter “leaks” onto other buttons

喜夏-厌秋 提交于 2019-12-10 12:55:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!