Cómo establecer programáticamente el atributo de estilo en una vista

Obtengo una vista del XML con el siguiente código:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null); 

Me gustaría establecer un “estilo” para el botón, ¿cómo puedo hacer eso en Java ya que quiero usar varios estilos para cada botón que usaré?

En general, no puede cambiar los estilos de forma programática; puede configurar el aspecto de una pantalla, o parte de un diseño, o un botón individual en su diseño XML utilizando temas o estilos . Los temas pueden, sin embargo, ser aplicados programáticamente .

También existe un StateListDrawable que le permite definir diferentes derivables para cada estado en el que puede estar su Button , ya sea enfocado, seleccionado, presionado, deshabilitado, etc.

Por ejemplo, para que su botón cambie de color cuando se lo presiona, puede definir un archivo XML llamado directorio res/drawable/my_button.xml siguiente manera:

      

A continuación, puede aplicar este selector a un Button configurando la propiedad android:background="@drawable/my_button" .

En primer lugar, no es necesario utilizar un inflador de diseño para crear un botón simple. Puedes simplemente usar:

 button = new Button(context); 

Si desea aplicarle un estilo al botón, tiene 2 opciones: la más simple es simplemente especificar todos los elementos en el código, como sugieren muchas de las otras respuestas:

 button.setTextColor(Color.RED); button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 

La otra opción es definir el estilo en XML y aplicarlo al botón. En el caso general, puede usar ContextThemeWrapper para esto:

 ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle); button = new Button(newContext); 

Para cambiar los atributos relacionados con el texto en un TextView (o sus subclases como Button) hay un método especial:

 button.setTextAppearance(context, R.style.MyTextStyle); 

Este último no se puede usar para cambiar todos los atributos; por ejemplo, para cambiar el relleno, debe usar ContextThemeWrapper . Pero para el color, el tamaño, etc. del texto, puede usar setTextAppearance .

Sí, puede usar, por ejemplo, en un botón

 Button b = new Button(this); b.setBackgroundResource(R.drawable.selector_test); 

Para cualquiera que esté buscando una respuesta material, vea esta publicación SO: Botones para colorear en Android con Material Design y AppCompat

Utilicé una combinación de esta respuesta para establecer el color de texto predeterminado del botón en blanco para mi botón: https://stackoverflow.com/a/32238489/3075340

A continuación, esta respuesta https://stackoverflow.com/a/34355919/3075340 para establecer programáticamente el color de fondo. El código para eso es:

 ViewCompat.setBackgroundTintList(your_colored_button, ContextCompat.getColorStateList(getContext(),R.color.your_custom_color)); 

your_colored_button puede ser solo un Button normal o un botón de AppCompat si lo desea; probé el código anterior con ambos tipos de botones y funciona.

EDIT: encontré que los dispositivos pre-lollipop no funcionan con el código anterior. Consulte esta publicación sobre cómo agregar compatibilidad con dispositivos pre-lollipop: https://stackoverflow.com/a/30277424/3075340

Básicamente haz esto:

 Button b = (Button) findViewById(R.id.button); ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color; Drawable d = b.getBackground(); if (b instanceof AppCompatButton) { // appcompat button replaces tint of its drawable background ((AppCompatButton)b).setSupportBackgroundTintList(c); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Lollipop button replaces tint of its drawable background // however it is not equal to d.setTintList(c) b.setBackgroundTintList(c); } else { // this should only happen if // * manually creating a Button instead of AppCompatButton // * LayoutInflater did not translate a Button to AppCompatButton d = DrawableCompat.wrap(d); DrawableCompat.setTintList(d, c); b.setBackgroundDrawable(d); } 

La respuesta de @Dayerman y @h_rules es correcta. Para dar un ejemplo elaborado con código, en la carpeta dibujable, cree un archivo xml llamado button_disabled.xml

      

Luego en Java,

 ((Button) findViewById(R.id.my_button)).setEnabled(false); ((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled); 

Esto establecerá la propiedad del botón en desactivado y establecerá el color en plateado.

[El color se define en color.xml como:

  #C0C0C0  

Puede hacer atributos de estilo de esta manera:

 Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle); 

en lugar de:

  

En tiempo de ejecución, sabes qué estilo quieres que tenga tu botón. Entonces, de antemano, en xml en la carpeta de diseño, puede tener todos los botones listos para usar con los estilos que necesita. Por lo tanto, en la carpeta de diseño, es posible que tenga un archivo llamado: button_style_1.xml. El contenido de ese archivo puede verse así:

   

Si está trabajando con fragmentos, en onCreateView infle ese botón, como:

 Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false); 

donde container es el contenedor de ViewGroup asociado con el método onCreateView que sobrescribe al crear su fragmento.

¿Necesita dos botones más? Los creas así:

 Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false); Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false); 

Puede personalizar esos botones:

 secondFirstStyleBtn.setText("My Second"); thirdFirstStyleBtn.setText("My Third"); 

Luego, agrega sus botones personalizados y estilizados al contenedor de diseño que también ha inflado en el método onCreateView:

 _stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer); _stylizedButtonsContainer.addView(firstStyleBtn); _stylizedButtonsContainer.addView(secondFirstStyleBtn); _stylizedButtonsContainer.addView(thirdFirstStyleBtn); 

Y así es como puedes trabajar dinámicamente con botones estilizados.

Dependiendo de los atributos de estilo que le gustaría cambiar, es posible que pueda usar la biblioteca de París:

 Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null); Paris.style(view).apply(R.style.YourStyle); 

Muchos atributos como background, padding, textSize, textColor, etc. son compatibles.

  • Lista de atributos soportados actualmente
  • Instrucciones de instalación

Descargo de responsabilidad: soy el autor de la biblioteca.

Si está utilizando la biblioteca de soporte, simplemente podría usar

 TextViewCompat.setTextAppearance(getContext(), R.style.AppTheme_TextStyle_ButtonDefault_Whatever); 

para TextViews y botones. Hay clases similares para el rest de Vistas 🙂

Me enfrenté al mismo problema recientemente. así es como lo resolví.

           
  • Usé LinearLayout con android: weightSum = “2”
  • Di los dos elementos hijos android: layout_weight = “1” (di cada 50% del espacio padre (ancho y alto))
  • Y finalmente, le di al elemento secundario diferentes colores de fondo para tener el efecto final.

Gracias !

Hice una interfaz de ayuda para esto utilizando el patrón de soporte.

 public interface StyleHolder { void applyStyle(V view); } 

Ahora, para cada estilo que desee usar de forma pragmática, simplemente implemente la interfaz, por ejemplo:

 public class ButtonStyleHolder implements StyleHolder 

Declara un estilo en tu attrs.xml , el estilo para este ejemplo es:

      

Aquí está el estilo declarado en styles.xml :

  

Y finalmente la implementación del titular del estilo:

 Button btn = new Button(context); StyleHolder 

Encontré esto muy útil, ya que puede reutilizarse fácilmente y mantiene el código limpio y detallado, recomendaría usarlo solo como una variable local para que podamos permitir que el recolector de basura haga su trabajo una vez que hayamos terminado de configurar todos los estilos. .