9

I have a button which contains a drawable and text. I want the background of the button to be different than the normal one provided (preferably a plain color). This works fine, I simply use the android:background attribute in the XML file and assign the color accordingly. However, I want the the background to change to a different color when selected or focused (state selector).

I attempted to create a selector in a drawable folder with the defined colors (which works well when working with the text of a button), like so:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_focused="true" android:state_pressed="false" android:color="@color/green" />
        <item android:state_focused="true" android:state_pressed="true" android:color="@color/green" />
        <item android:state_focused="false" android:state_pressed="true" android:color="@color/green" />
        <item android:color="@color/white" />
    </selector> 

and set this xml as the android:background attribute, like so:

android:background="@drawable/button_state"

but this causes a force close stating:

 Caused by: android.content.res.Resources$NotFoundException: File res/drawable/button_state.xml from drawable resource ID #0x7f020070

but the resource is there. Can you not customize the background state? If you can, how? or what am I doing wrong? Thanks for the help!

chRyNaN
  • 3,592
  • 5
  • 46
  • 74
  • 1
    You can definitely use a selector as a background drawable. Where exactly did you put `button_state.xml`? – Ted Hopp Dec 31 '12 at 18:46
  • I placed it in the drawable folder as I often do. And upon launch the app force closes so it must not acknowledge my xml file – chRyNaN Dec 31 '12 at 18:59
  • or perhaps it does recognize the xml file, for if I use it with the textColor attribute it works fine. Only when I use it with the background attribute it force closes – chRyNaN Dec 31 '12 at 19:01

2 Answers2

12

The xml you posted is suitable for a color state list, not a state list drawable. Try this instead:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" >
        <shape><solid android:color="@color/green"/></shape>
    </item>
    . . .
</selector>

Alternatively, put your existing file into res/color and use it as you would any other color. However, I don't remember if you can use a color state list directly as a background for a view.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Okay, just so I understand how this works correctly: when using a state selector for a background of a `button`, the background resources defined in the selector xml should be a `drawable`? – chRyNaN Dec 31 '12 at 19:17
  • 2
    @AndroidStudent - Exactly. There's a big difference (in Android's internals) between a state list drawable and a color state list. A drawable state list needs to reference other drawables only. It's a bit confusing because the API seems to allow color references to be used where drawable references are needed, but that's a convenience that doesn't work everywhere. – Ted Hopp Dec 31 '12 at 19:29
2

EXAMPLE:

XML file saved at res/color/button_text.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="#ffff0000"/> <!-- pressed -->
        <item android:state_focused="true"
              android:color="#ff0000ff"/> <!-- focused -->
        <item android:color="#ff000000"/> <!-- default -->
    </selector>
    This layout XML will apply the color list to a View:

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_text"
        android:textColor="@color/button_text" />

@color/button_text

res/color/button_text.xml

This is the example provided by Google in the ColorStateList Resource: https://developer.android.com/guide/topics/resources/color-list-resource.html

I think colorStateList must be used to change color of textView of a widget.

jarodsmk
  • 1,876
  • 2
  • 21
  • 40
navalkishoreb
  • 533
  • 2
  • 8
  • 16