2010-06-01 15 views
14

Otros questions dicen que el estilo no se puede establecer mediante programación, sino una View puede ser inicializa con un estilo como cuando se carga desde XML.Creación de una vista de Android con un estilo particular mediante programación

¿Cómo puedo inicializar un View con un estilo particular programáticamente (no en XML)? Intenté usar View(Context context, AttributeSet attrs, int defStyle), pero no sé en qué analizar el segundo argumento. Pasando en null no se muestra el View

Respuesta

4

AttributeSet contiene la lista de atributos especificados en xml (por ejemplo, layout_width, layout_height, etc.).

Si lo está pasando como nulo, entonces debe establecer explícitamente el alto/ancho de la vista.

+1

'AttributeSet' no parece tener un constructor. ¿Es posible construir esto sin usar xml? – Casebash

+0

@Casebash AFAIK, no puede construir AttributeSet sin usar xml. Puede establecer todas las propiedades usando las funciones proporcionadas por la clase. – Karan

13

Estoy teniendo el mismo problema, pero no he encontrado ninguna forma práctica de directamente establecer un estilo programáticamente, hasta ahora. Me gustaría llenar mi pantalla con muchos widgets, de un tipo determinado, digamos botones. No es práctico definirlos todos en el archivo de diseño. Me gustaría crearlos programáticamente, pero también me gustaría definir su estilo en un archivo xml de estilo.

La solución que he ideado consiste en definir solo uno de esos widgets en el archivo de diseño, crear todos los demás mediante programación y clonar la información de estilo del primero a los demás.

Sigue un ejemplo.

En el archivo de estilo, defina el estilo de sus botones. Por ejemplo:

<style name="niceButton"> 
    <item name="android:layout_width">160dip</item> 
    <item name="android:layout_height">60dip</item> 
    <item name="android:gravity">center</item> 
    <item name="android:textSize">18dip</item> 
    <item name="android:textColor">#000000</item> 
</style> 

Luego subclase clase "Botón", derivando una clase "NiceButton". Definir el constructor que será necesaria por el inflado:

public NiceButton(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

a continuación, definir otro constructor, lo cual es clonar un botón existente:

public NiceButton(int id, NiceButton origButton) { 
    super(origButton.getContext()); 
    setId(id); 
    setLayoutParams(origButton.getLayoutParams()); 
    setGravity(origButton.getGravity()); 
    setPadding(origButton.getPaddingLeft(), 
        origButton.getPaddingTop(), 
        origButton.getPaddingRight(), 
        origButton.getPaddingBottom()); 
    setTextSize(TypedValue.COMPLEX_UNIT_PX, origButton.getTextSize()); 
    setTextColor(origButton.getTextColors()); 
    // ... also copy whatever other attributes you care about 
} 

En el archivo de diseño, defina sólo el primero de tus botones Supongamos por ejemplo que usted quiere poner los botones en una tabla:

<TableLayout android:id="@+id/button_table" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 

    <TableRow android:id="@+id/button_row_0"> 
     <com.mydomain.mypackage.NiceButton 
        style="@style/niceButton" android:id="@+id/button_0" /> 
     <!-- More rows/buttons created programmatically --> 
    </TableRow> 

</TableLayout> 

en cuenta que se utiliza el nombre calificado completo de la clase Widget; obviamente, tendrá que reemplazar com.mydomain.mypackage con el nombre del paquete real.

En su actividad, es posible que desee definir una matriz que se va a celebrar una referencia a todos los botones, y un oyente común que se llamará cuando se pulsa cualquiera de los botones:

NiceButton[] mButtonViews = new NiceButton[10]; 

private View.OnClickListener mNiceButtonClickListener = new View.OnClickListener() { 
    public void onClick(View view) { 
     int i = view.getId(); 
     mButtonViews[i].setText("PRESSED!"); 
    } 
}; 

Observe cómo la ID de vista se usa como un índice en la matriz de botones. Por lo tanto, necesitará sus botones para tener una identificación de 0 a n-1.

Por último, aquí está la forma en que puede crear sus botones en el método onCreate:

// Retrieve some elements from the layout 
    TableLayout table = (TableLayout)findViewById(R.id.button_table); 
    TableRow row = (TableRow)findViewById(R.id.button_row_0); 
    NiceButton origButton = (NiceButton)findViewById(R.id.button_0); 

    // Prepare button 0 
    origButton.setId(0); 
    origButton.setText("Button 0"); 
    origButton.setOnClickListener(mNiceButtonClickListener); 
    mButtonViews[0] = origButton; 

    // Create buttons 1 to 10 
    for (int i = 1; i < 10; i++) { 
     if (i % 2 == 0) { 
      row = new TableRow(this); 
      table.addView(row); 
     } 
     NiceButton button = new NiceButton(i, origButton); 
     button.setText("Button " + i); 
     button.setOnClickListener(mNiceButtonClickListener); 
     mButtonViews[i] = button; 
     row.addView(button); 
    } 

es como aparece la pantalla después de pulsar algunos botones aquí: enter image description here

Bueno, hay algo de código involucrado, pero al final puede crear tantos widgets que desee mediante programación, y aún así tener sus atributos definidos como un estilo.

10

Si quieres estilo de una vista que tienen 2 opciones: la más simple es simplemente especificar todos los elementos de código:

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

La otra opción es definir el estilo en XML, y aplicarlo a la vista. 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

La mejor y más simple solución. Gracias. – Steelight

+0

setTextApperance() requiere API 23 – PaulrBear

+1

@PaulrBear, hay dos versiones, una se agregó en API 1 y obsoleta en 23, la otra se agregó en 23 – beetstra

Cuestiones relacionadas