Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify an xml StateListDrawable from java

I have a drawable defined in res/drawable/my_background.xml.

my_background.xml is:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <layer-list >
            <item android:drawable="@drawable/product_background_1" />
            <item>
                <rotate
                    android:fromDegrees="180"
                    android:toDegrees="180"
                    android:pivotX="50%"
                    android:pivotY="50%"
                    android:drawable="@drawable/product_background_2" 
                    android:id="@+id/need_to_change_this_color_from_java" />
            </item>
            <item><color android:color="#4400aa00"/></item>
        </layer-list>
    </item>
    <item>
        <layer-list >
            <item android:drawable="@drawable/product_background_1" />
            <item android:drawable="@drawable/product_background_2" />
        </layer-list>
    </item>
</selector>

I then set my_background as drawable on a view and that works fine.

But I need to change the value of a color element which is stored in a layerList in my selector from my java code. How do I do that?

I can call getBackground() on my view, and then get a StateListDrawable, but I can't find any method to get the drawable children from a StateListDrawable.

like image 807
MTilsted Avatar asked Jan 30 '14 15:01

MTilsted


1 Answers

...but I can't find any method to get the drawable children from a StateListDrawable.

You can access the children though the DrawableContainerState class of the super class DrawableContainer. That class has a getChildren() method which will return an array containing the two LayerDrawable. You can then further manipulate those drawable to get to the target drawable:

StateListDrawable sld = (StateListDrawable) theView.getBackground();
DrawableContainerState dcs = (DrawableContainerState) sld.getConstantState();
Drawable[] children = dcs.getChildren();
RotateDrawable target = (RotateDrawable) ((LayerDrawable) children[0]).getDrawable(1); // or use the id
// use target to change the color

Starting with KitKat(API level 19) DrawableContainerState exposes a getChild() method so you can retrieve the proper LayerDrawable directly.

like image 115
user Avatar answered Oct 05 '22 23:10

user