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'ssetColor()
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 aGradientDrawable
and not aShapeDrawable
. If you check out theinflate()
method ofGradientDrawable
in the source, you can get all the detail you could ask for on how each attribute is used.HTH!
In fact you can assign a
ColorStateList
as a solid color inside of the xml of a ashape
->GradientDrawable
, but that is only a new feature in Lollipop.Older versions of
GradientDrawable
only accept color resources.Currently working on a compat alternative if you are interested.
You are doing it wring .... just Replace this
with
update:
in your program code in the my_background_drawable.xml