¿Cómo configurar la imagen de fondo del botón de imagen para diferentes estados?

80

Quiero un botón de imagen con dos estados i) normal ii) táctil (o clic).

He configurado una imagen normal en el fondo del botón de imagen y estoy tratando de cambiar la imagen (presionada) desde el método onclick , pero no cambia.

Quiero que si presioné el botón de imagen, la imagen debería cambiar de normal a presionada hasta que presione otro botón, pero no sucede .

¿Alguien puede sugerirme cómo puedo hacer esto con el selector o en tiempo de ejecución ?

Aquí está mi código de panel de botones de imagen.

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

y mi selector xml es

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

Y también he intentado cambiar el recurso de la imagen en el evento ontouch y onclick, pero no ayuda.

Hitendra
fuente
Creo que estás buscando algo como esto . Hace una pregunta similar hice.
Federico klez Culloca

Respuestas:

224

Crea un archivo xml en tu dibujable como este:

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

Y configure las imágenes en consecuencia y luego configure este xml como fondo de su imageButton.

ingsaurabh
fuente
11
Correcto. esto se llamará Selector XMLs
Aman Alam
4
@Hitendra: supongo que la operación ya lo sabía. la pregunta se puede interpretar como por qué no se invoca el selector.
Samuel
¿Es necesario state_enabled?
Dr.jacky
4
Esto funciona para lo habitual Button, pero no ImageButton. También esto funcionaría para ImageButtonel android:srcatributo de, pero no android:background. ¿Y cuál es la diferencia entre el selector de OP y el suyo (excepto el formato y los nombres de los elementos de diseño)? Me estoy perdiendo de algo ?
Alexander Malakhov
@AlexanderMalakhov Para mí funciona muy bien para ImageButton y android: background.
Trilarion
15

Prueba esto

btn.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        btn.setBackgroundResource(R.drawable.icon);
    }
});
Parag Chauhan
fuente
¿Hay alguien con la idea de que puedo hacerlo?
Hitendra
9

mhh. Obtuve otra solución que me ayudó, porque solo tengo dos estados diferentes:

  • o no se hace clic en el elemento
  • o se hace clic y se resaltará

En mi .xml defino el ImageButton así:

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

El archivo selector correspondiente se ve así:

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

Y en mi onCreate llamo:

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

hecho. espero que esto ayude. Me tomó un tiempo averiguarlo.

bass.t
fuente
8

Hola, prueba el siguiente código que te será útil,

((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;
    }
});
VenkaReddy
fuente
1
en realidad, esto tampoco funciona realmente, si action_up ocurre en una vista diferente. intente usar event.getAction () == MotionEvent.ACTION_CANCEL en lugar de ACTION_UP.
chug2k
3

Creo que tu problema no es el archivo selector.

tienes que agregar

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

a sus botones de imagen.

de forma predeterminada, onClick se maneja a nivel de lista de elementos (padre). y los imageButtons no reciben el onClick.

cuando agregue el atributo anterior, el botón de imagen recibirá el evento y se utilizará el selector.

marque este POST que explica lo mismo para la casilla de verificación.

Samuel
fuente
1

si desea presionar el botón de imagen, la imagen debe cambiar de normal a presionada

Pero la mejor manera será personalizar RadioButton y usarlos en grupo. He visto un ejemplo de eso. Lo siento, no recordaba ese enlace.

pero si quieres evitar eso. Necesita agregar esto a su selector.xml

Una vez hecho. Solo tienes que acceder a tu código y agregar esto

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

Verás el resultado. Pero debe administrar los estados en los que se presionó el botón recientemente. Para que puedas configurar

  myOLDImageButton.setSelected ( false ) ;

Le sugiero que ponga todas las referencias de botón en una matriz.

Arslan Anwar
fuente
0

lo que intenta hacer es más un botón segmentado que una lista de botones de imagen.

aquí http://blog.bookworm.at/2010/10/segmented-controls-in-android.html es un ejemplo de cómo hacerlo. La idea básica es personalizar RadioButton en lugar de ImageButton, ya que RadioButton tendrá el estado marcado que necesita

njzk2
fuente
no ... no creo que eso es lo que quería. El control segmentado es un elemento de la interfaz de usuario completamente diferente. quiere 1 botón que cambia de estado.
Henley Chiu
0

¿Usted ha intentado CompoundButton? CompoundButton tiene la propiedad comprobable que se adapta exactamente a sus necesidades. Reemplace ImageButtons con estos.

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

Cambie el selector xml a lo siguiente. Puede necesitar algunas modificaciones, pero asegúrese de usar state_checkeden lugar de 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> 

En CompoundButton.OnCheckedChangeListenerdebe marcar y desmarcar otro según sus condiciones.

 mButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

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

De manera similar, configure a OnCheckedChangeListenerpara cada botón, que desmarcará otros botones cuando esté marcado. Espero que esto ayude.

Ronnie
fuente
No puede usar CompoundButton directamente en XML, ya que es una clase abstracta.
Dan Hulme
0

puedes crear un archivo selector en res / drawable

ejemplo: 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>

y en actividad de diseño, fragmento o etc.

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