2010-01-06 19 views

Respuesta

42

Generalmente no puede cambiar los estilos programáticamente; puede configurar el aspecto de una pantalla, o parte de un diseño, o botón individual en su diseño XML usando themes or styles. Los temas pueden, sin embargo, be applied programmatically.

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 obtener su botón para cambiar de color cuando se pulsa, se podría definir un archivo XML denominado res/drawable/my_button.xml directorio de la siguiente manera:

<?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/btn_pressed" /> 
    <item 
    android:state_pressed="false" 
    android:drawable="@drawable/btn_normal" /> 
</selector> 

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

+4

Mi problema es que cargo datos de un servicio web que describe la información de mi botón. Los botones deben tener un estilo diferente según la categoría a la que pertenecen. Es por eso que me gustaría establecer el estilo de forma dinámica. –

+2

Bueno, no puedes cambiar el atributo 'style' de Android, pero puedes establecer programáticamente el fondo de un' Botón' como lo haces con cualquier otra vista, si eso es suficiente. Además, como un 'Botón' hereda de' TextView', puede cambiar las propiedades del texto. Solo mire la documentación de API para estos artículos ... http://developer.android.com/reference/android/view/View.html#setBackgroundResource%28int%29 –

+0

Estaba pensando en hacer eso, justo antes de comprobar si Tenía nuevas respuestas. Muchas gracias. –

13

Sí, se puede utilizar por ejemplo en un botón

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

Eso configurará el fondo, pero un estilo puede especificar más que solo un fondo. Muchas vistas (incluido el botón) parecen tener un constructor que toma una ID de estilo como parámetro. Sin embargo, estoy teniendo problemas para que eso funcione para mí: el botón aparece como texto sin borde ni nada. Lo que podría hacer en su lugar es crear un diseño con solo un botón (con un estilo especificado), inflar ese diseño, luego configurar el texto del botón y otras cosas. – spaaarky21

5

La respuesta por @Dayerman y @h_rules es correcto. Para dar un ejemplo elaborado con código, En carpeta estirable, crear un archivo XML denominado button_disabled.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle" android:padding="10dp"> 
<solid android:color="@color/silver"/> 
<corners 
    android:bottomRightRadius="20dp" 
    android:bottomLeftRadius="20dp" 
    android:topLeftRadius="20dp" 
    android:topRightRadius="20dp"/> 
</shape> 

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 para discapacitados y conjuntos el color a plateado

[El color se define en color.xml como:

<resources> 

    <color name="silver">#C0C0C0</color> 

</resources> 
+0

El objetivo de esta pregunta es ** no ** para usar xml. – Pacerier

+3

@Pacerier: la pregunta no dice eso en absoluto. Es ambiguo si el estilo es XML o en Java. Solo pregunta cómo configurar el estilo mediante programación. – Harvey

24

En primer lugar, no es necesario utilizar un inflador de diseño para crear un simple botón. Usted sólo puede usar:

button = new Button(context); 

Si desea estilizar el botón que tiene 2 opciones: la más simple es simplemente especificar todos los elementos de código, como muchas de las otras respuestas ha sugerido:

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, se puede utilizar un 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 botón) 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 un ContextThemeWrapper. Pero para el color, el tamaño, etc. del texto, puede usar setTextAppearance.

+0

No es trabajo para mí. :( – offset

+1

Funciona solo para algunos atributos – D4rWiNS

+0

Simplemente brillante ContextThemeWrapper: es lo que estaba buscando desde hace tanto tiempo –

2

En tiempo de ejecución, ya 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 dicho archivo podría ser como:

<?xml version="1.0" encoding="utf-8"?> 
<Button 
    android:id="@+id/styleOneButton" 
    style="@style/FirstStyle" /> 

Si está trabajando con fragmentos, a continuación, en onCreateView se infla ese botón, como:

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

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

¿Necesita dos botones más? Se les crea de esta manera:

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 dichos botones:

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

Luego se agregan los, botones estilizados personalizadas al esquema del contenedor también se infla 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 puede trabajar dinámicamente con botones estilizados.

6

Para aquellos que buscan una respuesta Material de ver este SO mensaje: Coloring Buttons in Android with Material Design and AppCompat

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

Entonces esta respuesta https://stackoverflow.com/a/34355919/3075340 para establecer programáticamente el color de fondo. El código para que sea:

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

your_colored_button puede ser simplemente un botón regular de Button o una AppCompat si lo desea - He probado el código anterior con los dos tipos de botones y funciona.

EDIT: encontré que los dispositivos pre-lollipop no funcionan con el código anterior. Ver este post sobre cómo añadir soporte para dispositivos de pre-lollipop: https://stackoverflow.com/a/30277424/3075340

Básicamente hacer 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); 
} 
0

que enfrentan el mismo problema recientemente. así es como lo resolví.

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

    <!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background--> 
    <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 

    android:weightSum="2" 

    android:background="#FFFFFF" 
    android:orientation="horizontal" 
    > 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" 
     android:background="#0000FF" /> 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" 
     android:background="#F000F0" /> 
    </LinearLayout> 
    <!-- This is the special two colors background END--> 

    <TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
    android:gravity="center" 
    android:text="This Text is centered with a special backgound, 
    You can add as much elements as you want as child of this RelativeLayout" 
    android:textColor="#FFFFFF" 
    android:textSize="20sp" /> 
</RelativeLayout> 
  • I utilizó un LinearLayout con android: weightSum = "2"
  • di a los dos elementos secundarios androide: layout_weight = "1" (I dio a cada uno 50% del espacio de los padres (ancho & altura))
  • Y finalmente, le di al elemento secundario diferentes colores de fondo para tener el efecto final.

Gracias!

1

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

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

para TextViews y botones. Hay clases similares para el resto de Vistas :-)

4

Usted puede hacer atributos de estilo, así:

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

en lugar de:

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/btn" 
    style="?android:attr/buttonBarButtonStyle" 

    /> 
+0

Se debe crear una buena respuesta teniendo en cuenta un botón.Sería bueno ver cómo hacer eso para un botón existente. –

+0

Ver la respuesta de cesards. –

0

hice una interfaz de ayuda para este uso el patrón del titular.

public interface StyleHolder<V extends View> { 
    void applyStyle(V view); 
} 

Ahora para cada estilo que desea utilizar pragmáticamente acaba de implementar la interfaz, por ejemplo:

public class ButtonStyleHolder implements StyleHolder<Button> { 

    private final Drawable background; 
    private final ColorStateList textColor; 
    private final int textSize; 

    public ButtonStyleHolder(Context context) { 
     TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder); 

     Resources resources = context.getResources(); 

     background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background)); 

     textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor)); 

     textSize = ta.getDimensionPixelSize(
       ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize), 
       resources.getDimensionPixelSize(R.dimen.standard_text_size) 
     ); 

     // Don't forget to recycle! 
     ta.recycle(); 
    } 

    @Override 
    public void applyStyle(Button btn) { 
     btn.setBackground(background); 
     btn.setTextColor(textColor); 
     btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); 
    } 
} 

declarar una con estilos en su attrs.xml, el styleable para este ejemplo es:

<declare-styleable name="ButtonStyleHolder"> 
    <attr name="android:background" /> 
    <attr name="android:textSize" /> 
    <attr name="android:textColor" /> 
</declare-styleable> 

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

<style name="button"> 
    <item name="android:background">@drawable/button</item> 
    <item name="android:textColor">@color/light_text_color</item> 
    <item name="android:textSize">@dimen/standard_text_size</item> 
</style> 

Y por último, la aplicación del titular de estilo:

Button btn = new Button(context);  
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context); 
styleHolder.applyStyle(btn); 

Me pareció muy útil, ya que se puede reutilizar fácilmente y mantiene el código limpio y prolijo, yo recomendaría usar esto sólo como una variable local para podemos permitir que el recolector de basura haga su trabajo una vez que hayamos terminado de configurar todos los estilos.

Cuestiones relacionadas