Search code examples
androidxmlandroid-selector

Button - Change background color on click


I have 8 buttons in my activity. What I am looking for is, The buttons have a default background and when a button is clicked, the background color should change to some other color. This part is pretty straight forward. But, when I click on any other button, the background color of the first button should change back to default color. I understand that this will be done using "selector states", but I am not quite sure of how to implement it. The more i read about it, the more confused I am.

Right now, the xml that I have is as follows: in drawable folder

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/blue" android:state_pressed="true"/>
    <item android:drawable="@color/dark_grey" android:state_focused="true"/>  
    <item android:drawable="@drawable/image_border"/>

 </selector>

the drawable/image_border in the xml is used to define shape for the button. Below is the image_border.xml

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

    <solid android:color="@color/dark_grey" />

    <stroke
        android:width="4dp"
        android:color="@color/light_grey" />

    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

</shape>

Can someone help me with how to change the xml to behave the way I need it to be?

[EDIT 1]

All the below answers are pointing towards similar kind of solution. Here are the changes that I did. But, still, when i press the button, it turns to the specified color but immediately turns back to the default color.

button_background_blue.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/image_border_blue" android:state_pressed="true"/>
    <item android:drawable="@color/dark_grey" android:state_focused="true"/>  
    <item android:drawable="@drawable/image_border"/>

 </selector>

image_border_blue.xml

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

    <solid android:color="@color/blue" />

    <stroke
        android:width="4dp"
        android:color="@color/blue" />

    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

</shape>

Any thoughts?


Solution

  • Create a shape named button_pressed.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    
        <solid android:color="@color/blue" />
    
        <stroke
            android:width="4dp"
            android:color="@color/blue" />
    
        <padding
            android:bottom="1dp"
            android:left="1dp"
            android:right="1dp"
            android:top="1dp" />
    
    </shape>
    

    Suppose, you have two buttons whose IDs are R.id.btn and R.id.btn1

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="12dp"
            android:background="@drawable/button_pressed"
            android:onClick="onClick"
            android:text="Press Me 1" />
    
        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="12dp"
            android:background="@drawable/button_pressed"
            android:onClick="onClick"
            android:text="Press Me 2" />
    
    </LinearLayout>
    

    Write the onClick() method which will allow you to retain the changed color until another button is pressed.

    Button button;
    
    public void onClick(View v) {
    
        Drawable dr = getResources().getDrawable(R.drawable.button_pressed);
        dr.setColorFilter(Color.parseColor("#FF0000"), PorterDuff.Mode.SRC_ATOP);
    
        switch (v.getId()) {
        case R.id.btn:
    
            if (button == null) {
                button = (Button) findViewById(v.getId());
            } else {
                button.setBackgroundResource(R.drawable.button_pressed);
                button = (Button) findViewById(v.getId());
            }
            button.setBackgroundDrawable(dr);
    
            break;
    
        case R.id.btn2:
            if (button == null) {
                button = (Button) findViewById(v.getId());
            } else {
                button.setBackgroundResource(R.drawable.button_pressed);
                button = (Button) findViewById(v.getId());
            }
            button.setBackgroundDrawable(dr);
    
            break;
    
        default:
            break;
        }
    }
    

    I think, now you will get What you wanted to do.