123

I'm attempting to change the background color of an Android TextView widget when the user touches it. I've created a selector for that purpose, which is stored in res/color/selector.xml and roughly looks like that:

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

The clickable attribute of the TextView is true, in case that's of interest.

When I assign this selector to a TextView as android:background="@color/selector", I'm getting the following exception at runtime:

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

When I change the attribute to drawable, it works, but the result is looking completely wrong because the IDs appear to be interpreted as image references instead of color references (as the "drawable" suggests).

What confuses me is that I can set a color reference, e.g. "@color/black", as the background attribute directly. This is working as expected. Using selectors doesn't work.

I can also use the selector as the textColor without problems.

What's the correct way to apply a background-color-selector to a TextView in Android?

samis
  • 5,746
  • 6
  • 29
  • 64
digitalbreed
  • 3,080
  • 4
  • 21
  • 20
  • A color can be interpreted as a drawable. How is the result wrong exactly? – Romain Guy Aug 29 '10 at 01:40
  • It's not showing the color but an image from my drawable resources as the background instead. – digitalbreed Aug 29 '10 at 03:00
  • 2
    The above should work, if you use android:drawable, not android:color - at least in that case it works for me: android:drawable="@color/my_custom_color". My colors are defined in values/colors.xml – AgentKnopf Jan 21 '13 at 17:55

5 Answers5

229

The problem here is that you cannot define the background color using a color selector, you need a drawable selector. So, the necessary changes would look like this:

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

You would also need to move that resource to the drawable directory where it would make more sense since it's not a color selector per se.

Then you would have to create the res/drawable/selected_state.xml file like this:

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

and finally, you would use it like this:

android:background="@drawable/selector"

Note: the reason why the OP was getting an image resource drawn is probably because he tried to just reference his resource that was still in the color directory but using @drawable so he ended up with an ID collision, selecting the wrong resource.

Hope this can still help someone even if the OP probably has, I hope, solved his problem by now.

manfcas
  • 1,855
  • 6
  • 28
  • 46
Benoit Martin
  • 3,243
  • 2
  • 20
  • 22
  • 1
    Thanks, Benoit. The problem was solved (I must admit, I can't remember how exactly I did it in the end) and the project was successfully finished. I appreciate that you came back here to post and help people hitting the same problem in the future, great spirit! – digitalbreed Mar 24 '11 at 00:10
  • I can't make this work. I'm trying to apply it to a button and it does set the background to the default color of the selector, but it doesn't change to the shape defined in state_pressed. What could I be missing? I might open a new question, just in case you could point me in the right direction. – Maragues Apr 14 '11 at 18:00
  • @Maragues it's hard to tell without seeing any code. I'd recommend you open a new question and post the relevant code so we can figure out what could be wrong. You can add a comment to this post with a link to your new post too. – Benoit Martin Apr 14 '11 at 21:20
  • 9
    Why not simply use "drawable="@color/your_color" directly in your selector items instead? You don't need to define any shapes or any other files whatsoever, just have your color definitions in values/colors.xml (it's always good not to hardcode colors). – javaxian Apr 13 '14 at 13:37
  • Not working. Its showing me the different color than both i have declared in shape xml's. – Er.Rohit Sharma Jul 25 '16 at 15:13
  • One thing that was getting me for a long time with this: I thought my selector wasn't working, but it turns out my button just wasn't clickable, since I hadn't yet added the click listener. If anyone has problems with this, you might try using a selector that you know works for button presses to see if your button is indeed press-able. – Mark Aug 17 '16 at 22:27
  • Also add android:focusable="true" and android:clickable="true" to your textview – Saul_programa Jul 01 '18 at 06:10
122

Benoit's solution works, but you really don't need to incur the overhead to draw a shape. Since colors can be drawables, just define a color in a /res/values/colors.xml file:

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

And then use as such in your selector:

<?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>
Jenever
  • 421
  • 4
  • 16
azdev
  • 12,105
  • 6
  • 38
  • 45
  • For some reason, your solution is not showing the color but a random image from my drawable resources folder. I tried to clean the project/fix properties/resave/reopen eclipse as it seems really weird, but to no avail. Weird. – Yahel Jan 23 '12 at 15:26
  • @Yahel You possibly named the color drawable resource the same as an actual drawable file? – Jona Feb 01 '12 at 00:28
  • @Jona : Nope, but the drawable was named background_application and the color drawable was named background_white_transparent. Both had background in them...I have see on some other thread the same thing happen to others so I filed that as one of the numerous Android bugs and revamped my entire layout to workaround it. – Yahel Feb 01 '12 at 09:12
  • @Yahel Mmm... Well I see that issue but in my case not the same file names... Checkout my questions here http://stackoverflow.com/questions/9004744/imagebutton-background-swiching-on-its-own-drawables-gone-wild – Jona Feb 02 '12 at 04:19
  • didn't manage to make it work, the answer from Benoit Martin worked fine. – Emmanuel Touzery Jul 03 '12 at 13:00
84

An even simpler solution to the above:

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

Save that in the drawable folder and you're good to go.

Jason Robinson
  • 29,432
  • 18
  • 72
  • 128
17

Even this works.

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

I added the android:drawable attribute to each item, and their values are colors.

By the way, why do they say that color is one of the attributes of selector? They don't write that android:drawable is required.

Color State List Resource

<?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>
Maksim Dmitriev
  • 5,313
  • 9
  • 57
  • 124
  • color attribute works when you are setting on textview colors but not with background as actually the colors on backround are acted as ColorDrawable – Akhil Dad May 24 '15 at 14:10
  • Best and easiest solution to implement of all above. – 4gus71n Dec 21 '15 at 18:34
7

For who is searching to do it without creating a background sector, just add those lines to the TextView

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

Also to make it selectable use:

android:textIsSelectable="true"
Dasser Basyouni
  • 2,614
  • 3
  • 20
  • 43