2011-05-12 11 views
9

ayer noté la posibilidad de integrar Fragmentos en niveles API más antiguos a través del paquete de Compatibilidad, pero eso no es realmente esencial para la pregunta. :)android button setPressed after onClick

tengo un botón con un OnClickListener

Button button = (Button) findViewById(R.id.button); 
button.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     doSomething(); 
     button.setPressed(true); 
    } 
}); 

Debido a la real clic, se muestra tan presionado y después de soltar el clic, el estado del botón no se presiona y se mantiene de esa manera.

¿Hay alguna manera simple de mantener presionado el botón después de soltarlo? Lo primero que se me ocurre es algún tipo de temporizador, pero parece irrazonable.

+1

uso 'setSelected (estado booleano)' –

+1

Hola strem - ¿podría enumerar exactamente cómo te arreglaste? ¿Quiere decir que quiere que se muestre el botón pulsado durante un tiempo determinado hasta que se complete el evento? ¿O restablecer el botón presionado? De todos modos, muestre su solución porque la solución que seleccionó a continuación era incorrecta. –

Respuesta

6

Puede mantener los estados del botón en el archivo xml en la carpeta dibujable, y luego usarlos como fondo para el botón. Por ejemplo:

android:background="@drawable/buttonstate" 

buttonstate.xml

<?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/back_focused" /> 
    <item android:drawable="@drawable/back" /> <!-- default --> 
</selector> 
+12

no era exactamente lo que esperaba, ¡pero gracias de todos modos! funcionó ahora con button.setSelected (true) y defining un dibujable para ese estado – strem

+2

no es lo que el usuario preguntó, no resuelve el problema. Esta respuesta realmente no debería ser aprobada. – ChuckKelly

+0

Estoy de acuerdo con Chuck - strem - por favor, publique un ejemplo de cómo lo hizo con setSelected (true) si logró lograrlo de esa manera. ¿El botón vuelve al estado normal una vez que se completa la acción? –

23

para notar esto se debe a Android está cambiando la setPressed tanto antes como después de su onClickEvent, por lo que cambiar por sí mismo no tiene ningún efecto. Otra forma de evitar esto es usar el onTouchEvent.

button.setOnTouchListener(new OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 

     // show interest in events resulting from ACTION_DOWN 
     if (event.getAction() == MotionEvent.ACTION_DOWN) return true; 

     // don't handle event unless its ACTION_UP so "doSomething()" only runs once. 
     if (event.getAction() != MotionEvent.ACTION_UP) return false; 

     doSomething(); 
     button.setPressed(true);      
     return true; 
    } 
}); 
+1

Martin, su respuesta me gusta mucho. Sin embargo, cuando hago clic en el área de notificación o en el menú de opciones, el estado presionado desaparece. ¿Tienes alguna idea de lo que está pasando? – Couitchy

+0

no está claro en cuáles son las 2 declaraciones if para – ChuckKelly

13

Uso ToggleButton en lugar de Button.

<ToggleButton 
    android:id="@+id/button2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    android:background="@drawable/topping_selector" 
    android:checked="false" 
    android:textOff="Topping2" 
    android:textOn="Topping2" /> 

topping_selector.xml:

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

    <item android:state_checked="true" 
     android:drawable="@drawable/btn_topping_on" /> 

    <item android:state_checked="false" 
     android:drawable="@drawable/btn_topping_off" /> 

</selector> 
2

mejor solución:

en el archivo XML:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item android:state_activated="true"> 
     <bitmap android:src="@drawable/image_selected"/> 
    </item> 
    <item> 
     <bitmap android:src="@drawable/image_not_selected"/> 
    </item> 
</selector> 

Y en java:

@Override 
public void onClick(View v) { 
    v.setActivated(!v.isActivated()); 
} 
+1

Haha. Demasiadas líneas para una tarea simple: '' 'v.setActivated (! V.isActivated())' '' Pero gracias de todos modos – ruX

+0

si esta es la lógica, entonces no necesitas un selector para ... simplemente hacer cosas por ti mismo. mala solución ' – Khay

0

Otra solución es ampliar Button y anular el método setPressed(boolean pressed) para que pueda manejar las llamadas a la plataforma desde el onClickEvent usando un indicador, por ejemplo, cambiando el parámetro booleano presionado según sus necesidades.

public class MyButton extends Button { 
    boolean isSelected = false; //this is your flag 
    @Override 
    public void setPressed(boolean pressed) { 
     if(isSelected) { 
      //here you change the parameter so it stays pressed 
      super.setPressed(true); 
      return; 
     } 
     super.setPressed(pressed); 
    } 

    public void setIsSelected(boolean selected) { 
     this.isSelected = selected; 
    } 

    public MyButton(Context context) { 
     super(context); 
    } 
} 
3

Puede utilizar android.os.Handler clase. Feo, pero también funciona:

final Button button = (Button) findViewById(R.id.button); 
button.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     doSomething(); 
     new Handler().post(new Runnable() { 
      @Override 
      public void run() { 
       button.setPressed(true); 
      } 
     }); 
    } 
}); 
0

Esta es la solución que utilicé, también funciona en Android 7.0 en este momento.

YourActivity.java

public void onStandbyStart(String message) { 
    startStandbyBtn.setActivated(true); 
} 

public void onBackOnline(String message) { 
    startStandbyBtn.setActivated(false); 
} 

YourActivityLayout

<Button 
     ... 
     style="@style/generic_btn_style" 
     ... /> 

valores/styles.xml

<style name="generic_btn_style" parent="@android:style/Widget.Button"> 
     <item name="android:gravity">center_vertical|center_horizontal</item> 
     <item name="android:background">@drawable/generic_btn</item> 
     <item name="android:textColor">@color/selector_white_black</item> 
     <item name="android:focusable">true</item> 
     <item name="android:clickable">true</item> 
</style> 

estirable/generic_btn.xml Este selector selecciona el botón de bac Kground. Yo uso el presionado como el activado.

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

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@drawable/generic_btn_disabled" android:state_enabled="false" /> 
    <item android:drawable="@drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" /> 
    <item android:drawable="@drawable/generic_btn_pressed" android:state_activated="true" /> 
    <item android:drawable="@drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" /> 
    <item android:drawable="@drawable/generic_btn_enabled" android:state_enabled="true" /> 
</selector> 

de color/selector_black_white Aquí me puse el color del texto. En mi caso, tengo que elegir el textcolor negro cuando lo presiono.

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