Shape Drawable 中无法识别颜色状态列表

Posted

技术标签:

【中文标题】Shape Drawable 中无法识别颜色状态列表【英文标题】:Color State List not recognized in Shape Drawable 【发布时间】:2011-12-31 10:33:39 【问题描述】:

我定义了以下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>

我还定义了以下颜色状态列表资源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>

当我将给定的my_background_drawable 设置为某个视图的背景时,我无法观察到在color_stateful.xml 中为我的形状定义的颜色发生任何变化,而视图状态实际上发生了变化(selector_png_drawable.xml 是一个指示器)。

但是,当我通过以下方式修改 my_background_drawable.xml 时,一切都很好:

<?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>

那么当ColorStateList 资源在ShapeDrawable 中使用时,颜色状态信息是否会丢失,还是我做错了?

【问题讨论】:

【参考方案1】:

ColorStateList 不能作为 XML 定义中 &lt;solid&gt; 的属性传递,或者实际上是 &lt;shape&gt; 的任何属性。该属性作为 Color 资源从 XML 中膨胀出来,然后传递给 Drawable 的 setColor() 方法,该方法只接受一个 ARGB 值。

只有一种类型的 Drawable 实例旨在包含和呈现基于状态的多个项目,那就是 StateListDrawable,这是您在为 &lt;selector&gt; 充气时得到的。所有其他 Drawable 实例都只是该集合的成员或独立绘制。

还要注意,膨胀的&lt;shape&gt; 项目实际上是GradientDrawable 而不是ShapeDrawable。如果您查看 GradientDrawable in the source 的 inflate() 方法,您可以获得有关如何使用每个属性的所有详细信息。

HTH!

【讨论】:

从 Android Lollipop 开始,这不再适用,ColorStateList 被正确解析。 可以确认它在 Lollipop 中工作 - 真的很困惑为什么我的 对于棒棒糖之前的设备来说,显而易见(也是可怕的)替代方案是创建与状态一样多的&lt;shape&gt;s,每个状态仅通过&lt;solid&gt; color 属性不同,然后替换原始&lt;shape&gt; 可通过StateListDrawable 引用每个&lt;shape&gt; 绘制。通过仅使用 &lt;shape&gt; 元素内的资源引用(没有硬编码值)可以稍微减轻事情的暴行,并且还可以将原始 &lt;shape&gt; 保存在 drawable-v21 目录中(可能完全切换到之后)。 嘀咕【参考方案2】:

实际上,您可以将ColorStateList 指定为shape 的xml 内的纯色-> GradientDrawable,但这只是new feature in Lollipop。

Older versions of GradientDrawable只接受颜色资源。

如果您有兴趣,目前正在研究兼容的替代方案。

【讨论】:

【参考方案3】:

你正在绞尽脑汁....只需替换这个

   android:color="@color/color_stateful"

android:background="@color/color_stateful"

更新:

在 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:background="@color/color_stateful" /> <!--this is the chanage i made... here-->
        </shape>
    </item>

    <item android:drawable="@drawable/selector_png_drawable" />
</layer-list>

【讨论】:

shape drawable中没有android:background这样的属性

以上是关于Shape Drawable 中无法识别颜色状态列表的主要内容,如果未能解决你的问题,请参考以下文章

drawable下的shape

Android Drawable - Shape Drawable使用详解(附图)

Android Shape Drawable 改变属性

使用 shape drawable 作为我的背景 xml

Android 使用shape定义不同控件的的颜色背景色边框色

如何在代码中动态的设置shape