形状可绘制中未识别颜色状态列表。

13

我定义了以下可绘制的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>

那么,当在ShapeDrawable中使用ColorStateList资源时,颜色状态信息是否只是丢失了呢?或者是我的操作有误?

3个回答

25
在XML定义中,ColorStateList不能作为<shape>的任何属性,实际上也不能作为其它任何属性传递。此属性从XML膨胀出来作为颜色资源,并传递给Drawable的setColor()方法,该方法仅接受单个ARGB值。
只有一种类型的Drawable实例旨在基于状态包含和展示多个项目,那就是StateListDrawable,当你膨胀一个<selector>时就会得到它。所有其他Drawable实例都意味着简单地成为该集合的成员或独立绘制。
还要注意的是,膨胀的<shape>项实际上是一个GradientDrawable而不是ShapeDrawable。如果您查看GradientDrawableinflate()方法,可以在源代码中获取有关如何使用每个属性的所有详细信息。 希望对您有所帮助!

8
从 Android Lollipop 开始,这个说法不再正确,ColorStateList 被正确地解析了。 - keyboardr
1
可以确认它在棒棒糖中运行正常 - 我的小于21的测试设备为什么不能正常工作真的让我很困惑! - Tom
7
对于版本低于 Android 5.0 的设备,明显(而且可怕)的替代方法是为每个状态创建尽可能多的 <shape>,每个形状仅通过其 <solid>color 属性不同,然后将原始 <shape> drawable 替换为引用每个 <shape>StateListDrawable。这种方法的丑陋可以通过在 <shape> 元素中仅使用资源引用(没有硬编码值),并且可以将原始 <shape> 保留在 drawable-v21 目录中(以便可能完全切换到更高版本)来稍微缓解。blargh - desseim

2
实际上,您可以在 shape -> GradientDrawable 的 XML 中将 ColorStateList 分配为纯色,但这仅是 Lollipop 中的新功能旧版本的 GradientDrawable 只接受颜色资源。
如果您感兴趣,我目前正在开发一个兼容性替代方案。

-4

你做错了...只需要替换这个就可以了

   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>

1
在形状可绘制中,不存在 android:background 属性。 - a.ch.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接