如何在颜色状态列表资源中指定背景颜色?

20
为了给我的应用程序用户一个关于当前拥有焦点的字段的指示,我试图根据当前状态更改一些字段的背景颜色。然而,我在理解Android颜色状态列表资源方面遇到了困难。
我发现了一个例子(抱歉,URL不再可用),如果我尝试完全相同,即如果我想要适应textColor,事情确实起作用。但是,如果我尝试仅略微不同的事情,即调整背景颜色,事情却无法正常工作,我不明白为什么?为什么如此不一致?
为了使大家更容易理解我所做的事情,我附上了我的其他 .xml 文件:
AndroidManifest.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="mmo.android.test"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Test"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

Test-Activity

package mmo.android.test;

import android.app.Activity;
import android.os.Bundle;

public class Test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

res/values/strings.xml是一个文件路径。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, Test!</string>
    <string name="app_name">Test</string>
</resources>

res/color/button_test_color.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="#f0f"/> <!-- pressed -->
    <item android:state_focused="true"   android:color="#ff0"/> <!-- focused -->
    <item android:color="#000"/> <!-- default -->
</selector>

最后是我的res/layout/main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="foobar"
        android:textColor="@color/button_test_color"
        android:background="#f00"
     />
    <!-- 
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="foobar"
        android:textColor="#f00"
        android:background="@color/button_test_color"
     />
     -->
</LinearLayout>

如果我按照这里展示的方式运行它,它能正常工作,即我会得到一个按钮,其文本颜色会根据按钮是否被聚焦、按下等状态而改变。

如果我取消注释下面的按钮,其中我只是翻转了textColor和background的属性值,我会得到一个异常,指出

... <item> tag requires a 'drawable' attribute or child tag defining a drawable

我错在哪里了?为什么那个颜色状态列表可以作为文本颜色但不能作为背景颜色?如何根据视图的状态指定视图的背景颜色?

3个回答

66

我遇到了这个确切的问题。在我的看法中,android:background 在颜色状态列表中不起作用。我通过创建一个状态列表可绘制对象来解决了这个问题(可以在状态列表中使用单独的颜色作为可绘制对象)。

按照你的示例,创建一个文件 res/drawable/button_test_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"   android:drawable="@color/pressed_color"/>
    <item android:state_focused="true"   android:drawable="@color/focused_color"/>
    <item android:drawable="@color/default_color"/>
</selector>

注意使用 android:drawable 而不是 android:color。Android 将使用颜色资源并将其制作为 drawable。最后,您需要将颜色资源添加到 res/values/colors.xml 文件中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    ...
    <color name="pressed_color">#f0f</color>
    <color name="focused_color">#ff0</color>
    <color name="default_color">#000</color>
    ...
</resources>

那么,您可以使用 @drawable/button_test_background 来引用此可绘制对象,而不是使用 @color/button_test_color

简而言之,颜色状态列表可很好地用于 android:textColor,但对于 android:background,需要使用上述状态列表可绘制方法。


令人恼火。不过感谢你确认了我的怀疑。 - Mark

0

支持变体app:background允许直接使用颜色状态列表作为背景。

对于Android 10+,也可以使用android:background


这个不起作用。它编译通过但是没有改变颜色。看起来你必须在drawable中拥有状态列表。 - UnknownError

-1

尝试将textColor定义为可绘制对象,而不是颜色:

android:textColor="@drawable/button_test_color"

资源类别是基于它们的类型,而不是它们所在文件夹的名称。形式为button_test_color.xml的XML文件通常被称为“drawable” - 我实际上很惊讶“color”居然也能工作!


2
有关使用可绘制资源的更多信息,请参考此问题 - frayser
6
我不知道为什么这个答案被标记为正确。提问者似乎遵循了Android文档中的规定,即@color应该与res/color目录中的xml文件一起使用,并通过文件名引用。 - JulianSymes
我甚至更惊讶于这被选择为答案,当它根本不起作用。-1 - Sotti
不相关,不应该被接受的答案。原帖作者在使用ColorStateList时遇到了'background'属性的问题。 - SirKnigget

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