Wouter
Wouter

Reputation: 2653

Setting background colour on one object, changes another object

I have a TextView with a drawable as background. Using a StateListDrawable object I'm trying to set the background colour programmatically, but I'm running into unexpected behaviour: I set the colour in one object, and it changes in another. This should be impossible.

The relevant code:

    GradientDrawable notPressed = (GradientDrawable) getResources().getDrawable(R.drawable.rectangle);
    GradientDrawable isPressed = (GradientDrawable) getResources().getDrawable(R.drawable.rectangle);
    isPressed.setColor(util.getColour(api, this));

    StateListDrawable bg = new StateListDrawable();
    // bg.addState(new int[] { android.R.attr.state_pressed }, isPressed);
    bg.addState(StateSet.WILD_CARD, notPressed);

    textView.setBackgroundDrawable(bg);

The drawable:

<shape  xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
<stroke android:width="1dp" android:color="@color/divider" />
<solid android:color="@color/background_button" />
</shape>

util.getColour returns a colour resource based on the value of api.

The strange thing is that in the above code the colour of the isPressed drawable is set, but after that this drawable is not used. Instead only the notPressed drawable is added to the background of the textView.

But the background colour of the textView becomes the colour of the isPressed drawable instead! This should be impossible, as they should be two different objects, even if they are created from the same drawable resource.

Upvotes: 0

Views: 287

Answers (2)

Mr.Me
Mr.Me

Reputation: 9286

Android uses the same object for drawable resources unless you specify that you need a new copy of it.

you can use this code to solve this issue:

Drawable isPressed  = notPressed.getConstantState().newDrawable();

Upvotes: 0

dmon
dmon

Reputation: 30168

I think that when you get a resource you get the same reference to it. So notPressed and isPressed are the same object. I believe there's a clone operation somewhere...

Edit:

Yep, you have to call mutate() on the drawable before you modify it. See Adding a color filter to a Drawable changes all Buttons using the same Drawable.

Upvotes: 1

Related Questions