TextView背景颜色的选择器

126

我想要在用户触摸 Android TextView 组件时更改其背景颜色。我已创建了一个用于此目的的选择器,存储在 res/color/selector.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="@color/semitransparent_white"
        />
    <item
        android:color="@color/transparent"
        />
</selector>

TextViewclickable 属性为 true,如果这个对你有用的话。

当我把这个选择器作为 android:background="@color/selector" 分配给一个 TextView 时,在运行时会出现以下异常:

ERROR/AndroidRuntime(13130): Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #6: tag requires a 'drawable' attribute or child tag defining a drawable

当我将属性更改为 "drawable" 时,它可以工作,但是结果完全错误,因为ID似乎被解释为图像引用而不是颜色引用(如“drawable”所建议的那样)。

让我感到困惑的是,我可以直接将颜色引用,例如 "@color/black",作为背景属性设置,这个也按预期工作。但使用选择器却不行。

我也可以在没有问题的情况下将选择器用作 textColor

在 Android 中,将背景颜色选择器应用于 TextView 的正确方法是什么?


一种颜色可以被解释为可绘制对象。那么结果到底哪里出了问题? - Romain Guy
它没有显示颜色,而是作为背景显示了来自我的可绘制资源的图像。 - digitalbreed
2
以上应该可以正常工作,如果您使用android:drawable,而不是android:color-至少在这种情况下对我有效:android:drawable =“@ color / my_custom_color”。我的颜色定义在values / colors.xml中。 - AgentKnopf
5个回答

234

问题在于你不能使用颜色选择器来定义背景颜色,你需要使用一个可绘制选择器。因此,必要的更改如下:

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

你还需要将该资源移动到drawable目录中,因为它并不完全是颜色选择器,这样更加合理。

然后,你需要按照以下方式创建res/drawable/selected_state.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <solid android:color="@color/semitransparent_white" />
</shape>

最后,您将像这样使用它:

android:background="@drawable/selector"

注意: OP 之所以会得到一张图像资源,可能是因为他试图引用仍在 color 目录中但使用了@drawable的资源,导致 ID 冲突,选择了错误的资源。

希望即使 OP 可能已经解决了问题,这也能帮助其他人。


1
谢谢,Benoit。问题已经解决了(我必须承认,我不记得最后是怎么解决的),项目也成功完成了。我很感激你回来发布帖子并帮助那些未来遇到同样问题的人,这种精神太好了! - digitalbreed
@Maragues 如果没有看到任何代码,很难判断问题出在哪里。我建议您打开一个新的问题,并发布相关代码,以便我们找出可能存在的问题。您也可以在此帖子下添加评论,附上您新帖子的链接。 - Benoit Martin
9
为什么不直接在选择器项中使用“drawable = @color / your_color”?您无需定义任何形状或任何其他文件,只需在values / colors.xml中定义颜色即可(最好不要硬编码颜色)。 - javaxian
无法工作。它显示的颜色与我在形状 XML 中声明的两种颜色不同。 - Er.Rohit Sharma
有一件事情困扰了我很长时间:我以为我的选择器不起作用,但实际上是因为我还没有添加点击监听器,所以我的按钮无法被点击。如果有人遇到这个问题,可以尝试使用一个你知道可用于按钮按下的选择器来检查你的按钮是否确实可按。 - Mark
显示剩余2条评论

124

Benoit的解决方案可以工作,但你真的不需要承担绘制形状的开销。由于颜色可以是可绘制的,只需在/res/values/colors.xml文件中定义一个颜色:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="semitransparent_white">#77ffffff</color>
</resources>

然后在您的选择器中按此使用:

<?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/semitransparent_white" />
</selector>

由于某些原因,您的解决方案未显示颜色,而是从我的可绘制资源文件夹中随机显示图像。我尝试清理项目/修复属性/重新保存/重新打开Eclipse,因为它看起来非常奇怪,但无济于事。奇怪。 - Yahel
@Yahel 你可能将颜色可绘制资源与实际可绘制文件命名相同了? - Jona
@Jona: 没有,但是drawable的名称为“background_application”,而颜色drawable的名称为“background_white_transparent”。两者都含有背景(background)一词...我曾在其他帖子中看到过类似问题发生在其他人身上,因此我将其视为众多安卓(Android)错误之一,并重新设计了我的整个布局以解决该问题。 - Yahel
@Yahel 嗯...我看到了那个问题,但在我的情况下文件名不同...请查看我的问题,链接在这里:http://stackoverflow.com/questions/9004744/imagebutton-background-swiching-on-its-own-drawables-gone-wild - Jona
没能让它工作,Benoit Martin的答案很好用。 - Emmanuel Touzery

86

以下是一个更简单的解决方案:

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

将其保存在drawable文件夹中即可。


1
也许这个可以工作,但官方并不支持(Android Studio将其视为错误)。 - Blackhex
@Blackhex 奇怪。在我的Eclipse中可以正常工作。这可能是一个Lint错误,如果是的话,您应该能够禁用或忽略它。 - Jason Robinson
6
这是我认为的解决方案。 - Lay González
<item android:state_pressed="true" android:color="@color/vantablack"/> 看起来在语义上与 <item android:state_pressed="true"><color android:color="@color/vantablack"/></item> 一致。 - samus
在我的情况下,我需要将 <color android:color="@color/semitransparent_white" /> 更改为 <color android:drawable="@color/semitransparent_white" /> - Xianwei

17

即使这样也可以。

<?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/dim_orange_btn_pressed" />
    <item android:state_focused="true" android:drawable="@color/dim_orange_btn_pressed" />
    <item android:drawable="@android:color/white" />
</selector>

我在每个项目中添加了android:drawable属性,并将其值设置为颜色。

顺便问一下,为什么他们说colorselector的属性之一?他们没有写明需要android:drawable

颜色状态列表资源

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_window_focused=["true" | "false"] />
</selector>

颜色属性在设置TextView的文本颜色时有效,但在背景上无效,因为背景上的颜色实际上是作为ColorDrawable处理的。 - Akhil Dad
以上所有方案中最好和最容易实现的解决方案。 - 4gus71n

9

如果您想在不创建背景部分的情况下进行操作,只需将以下内容添加到TextView中即可:

android:background="?android:attr/selectableItemBackground"
android:clickable="true"

同时使其可选择,请使用以下方法:

android:textIsSelectable="true"

非常有用!!“android:attr”中还有其他有用的属性吗?谢谢。 - Zhou Hongbo

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