Android: Cómo actualizar el selector (StateListDrawable) mediante programación

Quiero actualizar el selector para un botón mediante programación.

Puedo hacer esto con el archivo xml que se da a continuación

<?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_off" /> <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_off" /> <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_on" /> <item android:state_enabled="true" android:drawable="@drawable/btn_on" /> </selector> 

Quiero hacer lo mismo programáticamente. He intentado algo como se indica a continuación

 private StateListDrawable setImageButtonState(int index) { StateListDrawable states = new StateListDrawable(); states.addState(new int[] {android.R.attr.stateNotNeeded},R.drawable.btn_off); states.addState(new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled},R.drawable.btn_off); states.addState(new int[] {android.R.attr.state_focused, android.R.attr.state_enabled},R.drawable.btn_on); states.addState(new int[] {android.R.attr.state_enabled},R.drawable.btn_on); return states; } 

Pero no funcionó.

Y cómo configurar android:state_enabled="false" o android:state_enabled="true" programatically.

Gracias por adelantado.

Es necesario utilizar el valor negativo del estado necesario. P.ej:

 states.addState(new int[] {-android.R.attr.state_enabled},R.drawable.btn_disabled); 

Observe el signo "-" antes de android.R.attr.state_enabled .

Muy tarde respuesta aquí, pero en caso de que alguien está teniendo problemas para establecer un StateListDrawable mediante programación. Entonces, como con los archivos XML, el orden en el que se establecen los estados en StateListDrawable es importante.

Por ejemplo, esto funcionará como se esperaba:

 StateListDrawable sld = new StateListDrawable(); sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY)); sld.addState(new int[] {}, new ColorDrawable(Color.GREEN)); 

Esto no:

 StateListDrawable sld = new StateListDrawable(); sld.addState(new int[] {}, new ColorDrawable(Color.GREEN)); sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY)); 

No es suficiente representante para comentar, pero la respuesta aceptada no funcionó para mí.

Mi objetivo era que los diseñadores establecieran los colores de fondo habilitados, deshabilitados y presionados en algún botón. Tenía la intención de que ellos lo usen para probar colores en diferentes pantallas.

Me di cuenta que algunas otras personas mencionaron que no funcionaba para ellos tampoco.

Los estados que necesitan ser definidos son

  • No se presiona y se activa, esto es lo que se ve cuando el botón está activado y no se presiona.
  • Presionado y activado, esto es lo que se ve cuando se presiona y se activa el botón
  • no disponible. Esto es lo que ves cuando el botón está desactivado

Aquí está un código que le dará una idea de los estados. Estoy utilizando Color.Parse () para generar ints para los colores entonces los paso a este método para conseguir el StateListDrawable.

 private StateListDrawable createDrawable(int enabled, int pressed, int disabled) { StateListDrawable stateListDrawable = new StateListDrawable(); stateListDrawable.addState(new int[] { -android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(enabled)); stateListDrawable.addState(new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(pressed)); stateListDrawable.addState(new int[] { -android.R.attr.state_enabled }, new ColorDrawable(disabled)); return stateListDrawable; } 

Voy a responder a su pregunta "¿Cómo actualizar el selector de un botón de forma programática?" LinearLayout cambiar un botón para un LinearLayout con ImageView incorporado y TextView . Hay una serie de beneficios a hacer esto, especialmente si más adelante decidirá personalizar sus puntos de vista. No hay pérdida de funcionalidad resultante de este conmutador. Todavía será capaz de adjuntar los mismos oyentes de eventos que puede adjuntar a un botón, pero será capaz de evitar los botones / pestañas denominación pesadillas. Aquí hay un código relevante del layout.xml

  <LinearLayout android:id="@+id/button" style="@style/ButtonStyle"> <ImageView android:id="@+id/background" android:src="@drawable/custom_image"/> <TextView style="@style/TextStyle" android:text="Custom Button" android:id="@+id/text"/> </LinearLayout> 

A continuación, tengo un archivo selector llamado custom_image.xml ubicado en la carpeta dibujable. Aquí está el contenido del archivo selector

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

Los tres archivos de imagen de origen (disabled_img.png, unselected_img.png, selected_img.png) también se encuentran en la carpeta dibujable.

Ahora regrese a su código Java. No hay necesidad de la funky StateListDrawable basura por muchas razones. En primer lugar, sólo se ve feo, y es difícil de mantener. Pero lo más importante es que va en contra de los principios de mantener su lógica independiente de su presentación. Si está gestionando sus recursos extraíbles en código Java, sabe que está haciendo algo mal fundametally.

Esto es lo que estoy proponiendo en su lugar. Siempre que quiera que su botón para ser seleccionado, sólo pop este one-liner en allí:

 ((LinearLayout)findViewById(R.id.button)).setSelected(true); 

O cuando quiera que el botón esté en el estado deshabilitado, aquí hay otro one-liner:

 ((ImageView)findViewById(R.id.background)).setEnabled(false); 

Observe por favor que en este último ejemplo estoy especificando el estado lisiado en el ImageView dentro del LinearLayout. Por alguna razón, siempre que cambie el estado habilitado / deshabilitado de LinearLayout, el selector no se está disparando. Funciona bien cuando lo hace en el ImageView en su lugar.

No sé cómo está agregando StateListDrawable , ya que el código no está aquí. Pero asegúrese de comprobar la documentación y agregar el setState() .

Puede configurar las propiedades desde la vista, como por ejemplo, yourView.setEnabled(true)

Espero que eso ayude

  • El botón no está llamando a OnClickListener con el primer clic
  • Android: botones de activación / desactivación de la masa
  • ¿Cómo hacer que el drawableLeft de un Android Button siga girando?
  • Obtener el color de fondo de un botón en android
  • ¿Es posible especificar el borde en el botón android?
  • cambio gradual del color del botón en androide
  • Práctica recomendada para definir eventos de botón en android
  • Color del borde del botón de Android
  • Agregar el botón de barra de acción con el cajón de navegación?
  • Diferencia entre el botón de la parte posterior de actionBar y el botón posterior de android
  • Cambiar entre el auricular y el altavoz al presionar el botón
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.