I define following drawable my_background_drawable.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:gravity="center"
android:shape="rectangle">
<solid android:color="@color/color_stateful" />
</shape>
</item>
<item android:drawable="@drawable/selector_png_drawable" />
</layer-list>
And I also define following color state list resource color_stateful.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:color="#FF00ff00"/>
<item android:color="#FFff0000"/>
</selector>
When I set given my_background_drawable
as a background for some view then I cannot observe any change in color defined in color_stateful.xml
for my shape, while the view state is actually changed (selector_png_drawable.xml
is an indicator).
However everything is just fine when I modify my my_background_drawable.xml
in the following way:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- This doesn't work
<item>
<shape android:gravity="center"
android:shape="rectangle">
<solid android:color="@color/color_stateful" />
</shape>
</item>
-->
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:gravity="center"
android:shape="rectangle">
<solid android:color="#FF00ff00" />
</shape>
</item>
<item>
<shape android:gravity="center"
android:shape="rectangle">
<solid android:color="#FFff0000" />
</shape>
</item>
</selector>
</item>
<item android:drawable="@drawable/selector_png_drawable"" />
</layer-list>
So is it true that color state information is just lost when ColorStateList
resource is used within a ShapeDrawable
or am I doing it wrong?
A ColorStateList
cannot be passed as an attribute for <solid>
in an XML definition, or really any attribute of a <shape>
. This attribute is inflated out of the XML as a Color resource and then passed to the Drawable's setColor()
method, which only takes a single ARGB value.
There is only one type of Drawable instance that is designed to contain and present multiple items based on state, and that is StateListDrawable
, which is what you get when you inflate a <selector>
. All other Drawable instances are meant to simply be members of this collection or drawn standalone.
Note also that an inflated <shape>
item is actually a GradientDrawable
and not a ShapeDrawable
. If you check out the inflate()
method of GradientDrawable
in the source, you can get all the detail you could ask for on how each attribute is used.
HTH!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With