lannyf lannyf - 2 months ago 13
Android Question

is the drawable a sington

got a behavior not sure if it is it should be.
If the drawable used in the view's background IS one instance shared with other views, how to change the individual's color?

having R.drawable.circle_shape as:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="10dip"/>
<solid android:color="#cccccc"/>
</shape>


used as two instances in one fragment

<ImageView
android:id="@+id/circle_1”
android:layout_width="22dp"
android:layout_height="22dp"
android:gravity="center"
android:layout_gravity="center"
android:background="@drawable/circle_shape"
android:shadowRadius="10.0"
/>

<ImageView
android:id="@+id/circle_2”
android:layout_width="22dp"
android:layout_height="22dp"
android:gravity="center"
android:layout_gravity="center"
android:background="@drawable/circle_shape"
android:shadowRadius="10.0"
/>


the other use is for the list item’s template in other fragment

<ImageView
android:id="@+id/listItem_image”
android:layout_width="22dp"
android:layout_height="22dp"
android:gravity="center"
android:layout_gravity="center"
android:background="@drawable/circle_shape"
android:shadowRadius="10.0"
/>


when do change the circle color for the instance c1, noticed the c2 and the listItem_image are all changed color.

View c1 = (View) findViewById(R.id. circle_1);
c1.setBackgroundResource(R.drawable.circle_shape); // with or without this it will still affect the other ImageView who also uses R.drawable.circle_shape as background

((GradientDrawable) c1.getBackground()).setColor(intColor);
((GradientDrawable) c1.getBackground()).setStroke(0, Color.TRANSPARENT);

Answer

Not really a singleton, but your guess is in the right direction. When you get a drawable, it shares state with other drawables. That's why when you modify one of them, you modify all the drawables which share state with it.

What you need to do is mutate drawable so that a new state is created. In your case it will look something like this:

GradientDrawable drawable = ((GradientDrawable) c1.getBackground()).mutate();
drawable.setColor(intColor);
drawable.setStroke(0, Color.TRANSPARENT);

The first line creates a new state, which allows the next two lines to change only the state of this particular drawable.

Comments