how to change background image of button when clicked/focused?
Asked Answered
F

9

42

I want to change the background image of a button when clicked or focused.

This is my code:

Button tiny = (Button)findViewById(R.id.tiny);
tiny.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        Button tiny = (Button)findViewById(R.id.tiny);
        tiny.setBackgroundResource(R.drawable.a9p_09_11_00754);

        TextView txt = (TextView)findViewById(R.id.txt);
        txt.setText("!---- On click ----!");
    }
});

Is this code right? Does it calls a button on its event?

Fu answered 18/10, 2011 at 6:47 Comment(0)
B
92

you can implement in a xml file for this as follows:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/your_imagename_while_focused"/>
<item android:state_pressed="true" android:drawable="@drawable/your_imagename_while_pressed" />
<item android:drawable="@drawable/image_name_while_notpressed" />  //means normal
</selector>

now save this xml file in drawable folder and name it suppos abc.xml and set it as follows

 Button tiny = (Button)findViewById(R.id.tiny);
 tiny.setBackgroundResource(R.drawable.abc);

Hope it will help you. :)

Boehm answered 18/10, 2011 at 6:54 Comment(7)
This neither works with API 22 or API 16. I tried implementing both through xml and programatically. The solution by @Chirag Raval works, on the other hand.Propellant
@JacobR, you said you tried both xml and programmatically ??? Chirag Raval's implementation is xml one only, then how it didn't work ??? Also mine is programmatically and it will work, you must be doing something wrong.Boehm
xml: android:background="@drawable/selector_drawable" programatically: v.setBackgroundResource(R.drawable.selector_drawable) Trying your answer, and the answer of @Chirag Raval the only difference was the content within the selector file. I do know that a long time ago, I used your implementation and it worked, while reusing that code today did not, so it's probably related to API.Propellant
will android still select the appropriate sized image from drawable-xhdpi, drawable-xxhdpi etc...? Or do we have to put a selector in each drawable forlder?Spoliate
How to do it without the XML file programmatically in my java class?Apropos
@Apropos it's mentioned in answer.Boehm
@deanresin, you don't have to. You can use one SVG file for the image.Boehm
S
58

Its very easy to implement . For that you need to create a one xml file(selector file) and put it in drawable folder in res. After that set xml file in button's background in your layout file.

button_background_selector.xml

<?xml version="1.0" encoding="UTF-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/your_hover_image" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/your_hover_image" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/your_hover_image"/>
    <item android:drawable="@drawable/your_simple_image" />
</selector>

Now set the above file in button's background.

<Button
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:textColor="@color/grey_text"
    android:background="@drawable/button_background_selector"/>
Scorch answered 18/10, 2011 at 6:55 Comment(2)
For anyone trying this approach and still struggling, make sure that <item android:drawable="@drawable/your_simple_image" /> is the LAST element in your selector. This is because the system will cycle through each element and choose the first one that matches. So if this is, say, the first element, it will match any state (pressed, focused or normal) and will therefore be selected every time - the other two drawables (the pressed and focused ones) will never be shown.Shuma
this should be the accepted answer, it really worked like a charm!Professor
M
9

Sorry this is wrong.

For changing background color/image based on the particular event(focus, press, normal), you need to define a button selector file and implement it as background for button.

For example: button_selector.xml (define this file inside the drawable folder)

<?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
           android:color="#000000" /> <!-- pressed -->
     <item android:state_focused="true"
           android:color="#000000" /> <!-- focused -->
     <item android:color="#FFFFFF" /> <!-- default -->
 </selector>

    <!-- IF you want image instead of color then write 
android:drawable="@drawable/your_image" inside the <item> tag -->

And apply it as:

 <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:drawable="@drawable/button_selector.xml" />
Myriad answered 18/10, 2011 at 6:51 Comment(6)
when i post my answer i dont know, he post it.Scorch
@Frankenstein just check my posted time. I was the 1st to reply if you can't see then.Myriad
@Frankenstein great interest. Let us do this kind of communication inside the chat.stackoverflow.comMyriad
i am waiting in Casual Chat room or Android or Android Discussion roomJourneyman
This question is either outdated or wrong. Even if you use colors you must use <item android:drawable="@color/my_color"... and not android:color.Goggle
How can I do it without having to create XML file programmatically in my java class. By getting different states of the view.Apropos
H
5

use this code create xml file in drawable folder name:button

<?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/buutton_pressed" />
  <item 
     android:drawable="@drawable/button_image" />
</selector>

and in button xml file

 android:background="@drawable/button"
Haymaker answered 18/10, 2011 at 7:2 Comment(0)
F
3

To change the button background we can follow 2 methods

  1. In the button OnClick, just add this code:

     public void onClick(View v) {
         if(v == buttonName) {
            buttonName.setBackgroundDrawable
             (getResources().getDrawable(R.drawable.imageName_selected));
          }
    
           }
    

    2.Create button_background.xml in the drawable folder.(using xml)

    res -> drawable -> button_background.xml

       <?xml version="1.0" encoding="UTF-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
             <item android:state_selected="true"
                   android:drawable="@drawable/tabs_selected" /> <!-- selected-->
             <item android:state_pressed="true"
                   android:drawable="@drawable/tabs_selected" /> <!-- pressed-->
             <item  android:drawable="@drawable/tabs_selected"/>
        </selector>
    

    Now set the above file in button's background file.

         <Button
               android:layout_width="fill_parent" 
               android:layout_height="wrap_content"
               android:background="@drawable/button_background"/>
    
                              (or)
    
             Button tiny = (Button)findViewById(R.id.tiny);
                   tiny.setBackgroundResource(R.drawable.abc);
    

    2nd method is better for setting the background fd button

Foveola answered 1/9, 2013 at 18:15 Comment(1)
Thanks @Foveola but this question has answered before.Fu
R
2

You just need to set background and give previous.xml file in background of button in your layout file.

<Button
 android:id="@+id/button1"
 android:background="@drawable/previous"
 android:layout_width="200dp"
 android:layout_height="126dp"
 android:text="Hello" />

and done.Edit Following is previous.xml file in drawable directory

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

<item android:drawable="@drawable/onclick" android:state_selected="true"></item>
<item android:drawable="@drawable/onclick" android:state_pressed="true"></item>
<item android:drawable="@drawable/normal"></item>

Rameriz answered 10/6, 2013 at 9:11 Comment(1)
This question has answered before.Fu
A
0

You can also create shapes directly inside the item tag, in case you want to add some more details to your view, like this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <solid android:color="#81ba73" />
            <corners android:radius="6dp" />
        </shape>
        <ripple android:color="#c62828"/>
    </item>
    <item android:state_enabled="false">
        <shape>
            <solid android:color="#788e73" />
            <corners android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="#add8a3" />
            <corners android:radius="6dp" />
        </shape>
    </item>
</selector>

Beware that Android will cycle through the items from top to bottom, therefore, you must place the item without condition on the bottom of the list (so it acts like a default/fallback).

Annelieseannelise answered 24/9, 2018 at 15:36 Comment(0)
D
0
  1. Create a file in drawable play_pause.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true"
          android:drawable="@drawable/pause" />

    <item android:state_selected="false"
          android:drawable="@drawable/play" />
    <!-- default -->
</selector>
  1. In xml file add this below code
 <ImageView
                android:id="@+id/iv_play"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="@dimen/_50sdp"
                android:layout_centerInParent="true"
                android:layout_centerHorizontal="true"
                android:background="@drawable/pause_button"
                android:gravity="center"
                android:scaleType="fitXY" />
  1. In java file add this below code
iv_play = (ImageView) findViewById(R.id.iv_play);
iv_play.setSelected(false);

and also add this

iv_play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                iv_play.setSelected(!iv_play.isSelected());
                if (iv_play.isSelected()) {
                    ((GifDrawable) gif_1.getDrawable()).start();
                    ((GifDrawable) gif_2.getDrawable()).start();
                } else {
                    iv_play.setSelected(false);
                    ((GifDrawable) gif_1.getDrawable()).stop();
                    ((GifDrawable) gif_2.getDrawable()).stop();
                }
            }
        });
Deodorant answered 15/5, 2019 at 6:34 Comment(0)
W
0

use <androidx.appcompat.widget.AppCompatButton /> instead of 'Button'

Willams answered 16/3, 2022 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.