119

I am trying to make a button with a selector my button can have the following states:

  • Enabled/Disabled
  • Pressed/Not Pressed

According to the states mentioned above. I need to manipulate the button's:

  • Text color
  • background image

The button starts off my being disabled so it should have the disabled textColor and the disabled button background. But I can see the default textColor (specified in style) and NO background image!

Here is my selector button_selector.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="false"
        android:state_enabled="false"
        android:textColor="#9D9FA2"
        android:drawable="@drawable/button" />    

    <item android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/button_pressed"/>

    <item android:state_pressed="true"
        android:state_enabled="false"
        android:textColor="#9D9FA2"
        android:drawable="@drawable/button"/>

    <item android:state_pressed="false"
        android:state_enabled="true"
        android:drawable="@drawable/button"/>    

</selector>

And here is my button declaration in the my layout.xml

    <Button android:id="@+id/reserve_button"
        android:text="@string/reserve_button"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="20dp"
        android:paddingRight="15dp"
        android:layout_gravity="left"
        style="@style/buttonStyle"
        android:background="@drawable/button_selector" />

And finally this is my style (where my default textColor is set)

<?xml version="1.0" encoding="utf-8"?>

 <resources>

     <style name="buttonStyle">
      <item name="android:textStyle">bold</item>
      <item name="android:textColor">#282780</item>
      <item name="android:textSize">18sp</item>
     </style>

</resources>

Please help!

Nouran H
  • 1,992
  • 5
  • 18
  • 24

5 Answers5

281

You need to also create a ColorStateList for text colors identifying different states.

Do the following:

  1. Create another XML file in res\color named something like text_color.xml.

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <!-- disabled state -->
      <item android:state_enabled="false" android:color="#9D9FA2" /> 
      <item android:color="#000"/>
    </selector>
    
  2. In your style.xml, put a reference to that text_color.xml file as follows:

    <style name="buttonStyle" parent="@android:style/Widget.Button">
      <item name="android:textStyle">bold</item>
      <item name="android:textColor">@color/text_color</item>
      <item name="android:textSize">18sp</item>
    </style>
    

This should resolve your issue.

Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
Adil Soomro
  • 37,609
  • 9
  • 103
  • 153
  • 1
    don't you need to save your text_color.xml file in /res/drawable (rather than /res/color) if you refer to it by @drawable/text_color ? – Erwan May 15 '13 at 09:15
  • 1
    @Erwan thanks for correction. actually if you see the edit history, I posted it as drawable folder, and some nice guy edited it to color but forgot to update it to `@color` in buttyStyle. Now its updated. – Adil Soomro May 15 '13 at 09:40
  • 7
    `text_color.xml` does not compile (for me, at least) unless I place it in the `drawable` folder, which the requires referring to it as `@drawable/text_color` – Al Lelopath Mar 07 '14 at 15:20
  • @mickey yes, you are correct, so if you see the edit history, it was initially suggested in drawable, but someone updated it to color folder, I've now rectified it. – Adil Soomro Mar 03 '15 at 16:17
  • @AdilSoomro just tried it, for me it only works when it's in `@color/text_color.xml`. You have it set correctly in your other answer: http://stackoverflow.com/questions/8743584/how-to-set-the-text-style-of-a-button-in-selectors. I updated your answer. – C0D3LIC1OU5 Nov 11 '15 at 23:21
  • 1
    @D3LIC1OU5 if you look at the comments, both ways have been told to work. I just consulted documentation and `color` is correct folder for [Color State List Resource](http://developer.android.com/guide/topics/resources/color-list-resource.html) Your edit is welcome. – Adil Soomro Nov 11 '15 at 23:30
  • To set the color state list programmatically, you need to use something like this: `button.setTextColor(ResourcesCompat.getColorStateList(resources, R.drawable.text_color, null));` Note you can put the text_color.xml file in `res/drawables` instead of `res/color`. – CorayThan Jan 27 '17 at 17:05
  • I didn't have to define the style. I could reference selector directly from the button's textColor. sdk 27 – Armai Feb 08 '21 at 10:59
  • @Armai yes, however style is helpful in applying same theme to multiple screen or many buttons. So you change from one place and it applies to all buttons/screens. – Adil Soomro Feb 08 '21 at 11:23
12

1.Create a color folder in /res/ folder and in color folder create on xml:

text_color_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- disabled state --> 
    <item android:state_enabled="false" android:color="#776678" /> 
    <item android:color="#ffffff"/>
</selector>

2.Now Create a xml layout:

 <Button
     android:id="@+id/button_search"
     android:layout_width="652dp"
     android:layout_height="48dp"
     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true"
     android:layout_marginTop="18dp"
     android:background="@android:color/transparent"
     android:text="Hello Bhaskar"
     android:textColor="@color/text_color_selector"/>  
Peter
  • 340
  • 4
  • 13
4

The most easy solution is to set color filter to the background image of and button as I saw here

You can do as follow:

if ('need to set button disable')
    button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
    button.getBackground().setColorFilter(null);

Hope I helped someone...

Community
  • 1
  • 1
Woody
  • 1,589
  • 14
  • 16
  • This is a nice way to do this dynamically, when you don't have the button background image in advance. But this doesn't take care of the text color. – Eran Goldin Aug 29 '14 at 08:17
0

You can create a color list

file location:

res/color/filename.xml

The filename will be used as the resource ID.

resource reference:

In Java: R.color.filename

In XML: @[package:]color/filename

syntax:

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

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" />

Refer: Color List Reference

Lal Krishna
  • 15,485
  • 6
  • 64
  • 84
-1
<Button android:id="@+id/reserve_button"
        android:text="@string/reserve_button"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="20dp"
        android:paddingRight="15dp"
        android:layout_gravity="left"
        style="@style/buttonStyle"
        android:background="@drawable/button_selector" />

I cannot see diabling of your button in your layout xml. add this to your button layout.

android:enabled="false"

so your Button layout will be,

<Button android:id="@+id/reserve_button"
        android:text="@string/reserve_button"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="20dp"
        android:enabled="false"
        android:paddingRight="15dp"
        android:layout_gravity="left"
        style="@style/buttonStyle"
        android:background="@drawable/button_selector" />
Aqif Hamid
  • 3,511
  • 4
  • 25
  • 38