How to set image button backgroundimage for different state?

AndroidAndroid Layout

Android Problem Overview


I want imagebutton with two states i) normal ii) touch(or click).

I have set normal image in the imagebutton background and I am trying to change image(pressed) from onclick method, but it doesn't change.

I want that if I pressed image button then image should change from normal to pressed until I press other button but it doesn't happen.

Can anyone suggest to me how can I do this with selector or at run time?

Here is my imagebuttonpanel code.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal"
  android:gravity="bottom"
  android:id="@+id/buttonpanel">
  <ImageButton android:id="@+id/buttonhome"
               android:layout_width="80dp"
               android:layout_height="36dp"
               android:focusable="true" 
               android:background="@drawable/homeselector">
               </ImageButton>
  <ImageButton android:id="@+id/buttonsearch"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/searchselector"
               android:focusable="true">
               </ImageButton>>
  <ImageButton android:id="@+id/buttonreg"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/registerselector"
               android:focusable="true">
               </ImageButton>>
  <ImageButton android:id="@+id/buttonlogin"
               android:layout_height="36dp"
               android:layout_width="80dp"
               android:background="@drawable/loginselector"
               android:focusable="true">
               </ImageButton>
</LinearLayout>

and my selector xml is

<?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/homehover" 
		/> <item android:state_focused="true" android:drawable="@drawable/homehover" 
		/> <item android:drawable="@drawable/home" /> <item android:state_window_focused="true" 
		android:drawable="@drawable/homehover" /> -->
	<item android:state_enabled="false" android:drawable="@drawable/homehover" />
	<item android:state_pressed="true" android:state_enabled="true"
		android:drawable="@drawable/homehover" />
	<item android:state_focused="true" android:state_enabled="true"
		android:drawable="@drawable/homehover" />
	<item android:state_enabled="true" android:drawable="@drawable/home" />

</selector> 

And I have also tried to change image resource on ontouch and onclick event, but it does not help.

Android Solutions


Solution 1 - Android

Create an xml file in your drawable like this :

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
		android:state_enabled="false"
		android:drawable="@drawable/btn_sendemail_disable" />
	<item
		android:state_pressed="true"
		android:state_enabled="true"
		android:drawable="@drawable/btn_send_email_click" />
	<item
		android:state_focused="true"
		android:state_enabled="true"
		android:drawable="@drawable/btn_sendemail_roll" />
	<item
		android:state_enabled="true"
		android:drawable="@drawable/btn_sendemail" />
</selector>

And set images accordingly and then set this xml as background of your imageButton.

Solution 2 - Android

Try this

btn.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        btn.setBackgroundResource(R.drawable.icon);
    }
});

Solution 3 - Android

mhh. I got another solution which helped me, 'cause I just have two different sates:

  • either the item is not clicked
  • or it is clicked and so it will be highlighted

In my .xml I define the ImageButton like this:

 <ImageButton
    android:id="@+id/imageButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/selector" />

The corresponding selector file looks like this:

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

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

</selector>

And in my onCreate I call:

final ImageButton ib = (ImageButton) value.findViewById(R.id.imageButton);

	OnClickListener ocl =new OnClickListener() {
		@Override
		public void onClick(View button) {
			if (button.isSelected()){
				button.setSelected(false);
			} else {
				ib.setSelected(false);
				//put all the other buttons you might want to disable here...
				button.setSelected(true);
			}
		}
	};

ib.setOnClickListener(ocl);
//add ocl to all the other buttons

done. hope this helps. took me a while to figure out.

Solution 4 - Android

Hi try the following code it will be useful to you,

((ImageView)findViewById(R.id.ImageViewButton)).setOnTouchListener(new View.OnTouchListener() {
	public boolean onTouch(View v, MotionEvent event) {
		if(event.getAction() == MotionEvent.ACTION_DOWN)
		    ((ImageView) v.findViewById(R.id.ImageViewButton)).setImageResource(R.drawable.image_over);

		if(event.getAction() == MotionEvent.ACTION_UP)
			((ImageView) v.findViewById(R.id.ImageViewButton)).setImageResource(R.drawable.image_normal);

		return false;
	}
});

Solution 5 - Android

i think you problem is not the selector file.

you have to add

<imagebutton ..
    android:clickable="true"
/>

to your image buttons.

by default the onClick is handled at the listitem level (parent). and the imageButtons dont recieve the onClick.

when you add the above attribute the image button will receive the event and the selector will be used.

check this POST which explains the same for checkbox.

Solution 6 - Android

what you are trying to do is more a segmentedbutton than an imagebutton list.

here http://blog.bookworm.at/2010/10/segmented-controls-in-android.html is an example on how to do so. The basic idea is to customize RadioButton instead of ImageButton, since the RadioButton will have the checked state you need

Solution 7 - Android

if you want pressed image button then image should be change from normal to pressed

But I best way will be to customize the RadioButton and use them in a group. I have see an example of that. Sorry I did not remember that link.

but if you want to avoid that. You need to add this to your selector.xml

Once Done. Just got to your code and add this

public void onClick ( View v ) {
    myImageButton.setSelected ( true ) ;
 }

You will see the result. But you have to mange the states which button was recently press. So that you can set

  myOLDImageButton.setSelected ( false ) ;

I suggest you to put all button reference in a array.

Solution 8 - Android

Have you tried CompoundButton? CompoundButton has the checkable property that exactly matches your need. Replace ImageButtons with these.

  <CompoundButton android:id="@+id/buttonhome"
                  android:layout_width="80dp"
                  android:layout_height="36dp"
                  android:background="@drawable/homeselector"/>

Change selector xml to the following. May need some modification but be sure to use state_checked in place of state_pressed.

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

</selector> 

In CompoundButton.OnCheckedChangeListener you need to check and uncheck other based on your conditions.

 mButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

   public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            // Uncheck others. 
        }
   }
});

Similarly set a OnCheckedChangeListener to each button, which will uncheck other buttons when it is checked. Hope this Helps.

Solution 9 - Android

you can create selector file in res/drawable

example: res/drawable/selector_button.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/btn_enabled" />
</selector>

and in layout activity, fragment or etc

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/selector_bg_rectangle_black"/>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHitendraView Question on Stackoverflow
Solution 1 - AndroidingsaurabhView Answer on Stackoverflow
Solution 2 - AndroidParag ChauhanView Answer on Stackoverflow
Solution 3 - Androidbass.tView Answer on Stackoverflow
Solution 4 - AndroidVenkaReddyView Answer on Stackoverflow
Solution 5 - AndroidSamuelView Answer on Stackoverflow
Solution 6 - Androidnjzk2View Answer on Stackoverflow
Solution 7 - AndroidArslan AnwarView Answer on Stackoverflow
Solution 8 - AndroidRonnieView Answer on Stackoverflow
Solution 9 - AndroidRasoul MiriView Answer on Stackoverflow