Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color/drawable changes are applied to all views with the same background (color) [Marshmallow]

Tags:

android

I've recently updated my phone to Android Marshmallow and ran my existing app on it, but noticed a difference in color behavior: When applying changes to the background of a view (drawable), all views that share the same background (reference) will also the same changes applied. While previously, this was not the case.

Example
In this example, I have a two views with the same background color, and I want to change the alpha level of one of both views.

First we define the views in the layout:

    <LinearLayout
        android:id="@+id/test1"
        android:orientation="horizontal"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/testColor2">

    </LinearLayout>

    <LinearLayout
        android:id="@+id/test2"
        android:orientation="horizontal"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/testColor1"
        android:layout_marginLeft="5dp">
    </LinearLayout>

Both views share the same background color or drawable:

<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>

The result looks like this:
enter image description here

Now we are going to change one of the two background, like this:

    LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
    LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
    test1.getBackground().setAlpha(80);

Which results in this:
enter image description here

However, the desired and expected result is obviously this:
enter image description here

Download the sample project here.

A few thoughs:

  • When setting the Alpha level trough XML, this behavior does not apply.
  • It does not matter if both views refer to a different color definition in colors.xml (like in the example), refer to the same color definition of both have the same color (hex) directly in the view's xml file.

Question
How can I make changes to a view's background without this affecting other views that share the same background. Preferably while still being able to use a background that directly refers to a color defined in the color's xml file

like image 691
Mdlc Avatar asked Oct 26 '15 20:10

Mdlc


People also ask

How do I change the color of a drawable in XML?

Use app:drawableTint="@color/yourColor" in the xml instade android:drawableTint="@color/yourColor" . It has the backward compatibility.

What is color drawable android?

android.graphics.drawable.ColorDrawable. A specialized Drawable that fills the Canvas with a specified color. Note that a ColorDrawable ignores the ColorFilter. It can be defined in an XML file with the <color> element.

How do you change the background color on Kotlin?

To set Android Button background color, we can assign android:backgroundTint XML attribute for Button in layout file with the required Color Value. To programmatically set or change Android Button background color, we may call pass the method Button.


1 Answers

Most likely the class of each view's background and constantstate are the same object. It seems as if the two color resources have been "merged" somewhere -- meaning they have shared ConstantState. Maybe in the Resources class' caching? I would've expected them to stay separate since they're different resources (albeit with the same color value), but apparently not.

– Snild Dolkow

The ColorDrawable's state stores alpha, so any changes to one will change the others. To prevent this, you can first call mutate() on the drawable, separating the two drawables (by making a copy of the state).

In the example, this would result in using test1.getBackground().mutate().setAlpha(80); instead of directly applying the alpha.

like image 171
Mdlc Avatar answered Oct 22 '22 04:10

Mdlc