2012-06-22 9 views
6

Tengo la siguiente vista de botón personalizado.Aplicación de estilo a las vistas dinámicamente en código Java

public class PrayerTimeLabel extends Button { 

int hours; 
int minutes; 
String dayHalf; //am or pm 
Context parentActivity; 
PrayerControl parentControl; 

public PrayerTimeLabel(Context context,PrayerControl parent) { 
    super(context);     
    init(context,parent,0); 
} 

public PrayerTimeLabel(Context context, int defStyle, PrayerControl parent) { 
    //super(context, null, R.style.Button_PrayerTimeButton); 
    super(context, null, defStyle);    
    init(context,parent,defStyle); 
} 


private void init(final Context context, PrayerControl parent, int defStyle) 
{   
    parentActivity = context; 
    parentControl = parent; 
    Typeface tf = Typeface.createFromAsset(context.getAssets(),"fonts/digital.ttf"); 
    this.setTypeface(tf);  
    this.setText(false); 

    this.setOnClickListener(new OnClickListener() {   
     public void onClick(View v) { 
      TimeDialog dialogBox = parentControl.getDialogBox(); 
      dialogBox.setTime(hours, minutes, dayHalf); 
      dialogBox.show(); 
     } 
    }); 
} 


public void setTime(int hrs, int min, String half,boolean signalParent) 
{ 
    hours = hrs; 
    minutes = min; 
    dayHalf = half; 
    this.setText(signalParent); 
} 

public void setText(boolean signalParent) 
{ 
    super.setText(String.format("%02d", hours)+":"+String.format("%02d", minutes)+" "+dayHalf); 
    if(signalParent){ 
     parentControl.setPrayerTime(hours, minutes, dayHalf); 
    } 
} 

} 

y tengo el siguiente estilo definido en mi style.xml

<style name="Button.PrayerTimeButton" parent="@android:style/TextAppearance.Widget.Button"> 
    <item name="android:background">#000</item> 
    <item name="android:textSize">18dp</item> 
    <item name="android:textColor">#FFFF00</item> 
</style> 

El botón extendido no está recibiendo este estilo. ¿Puede alguien señalar nuestro lo que estoy haciendo mal? Busqué la solución y encontré this. ¿Puede alguien sugerir algo

Nota: No puedo usar XML para aplicar estilos. Tiene que ser constructor.

Editar:

siguiente es la clase en la que se crea y utiliza este botón personalizado. He borrado muchas líneas de código irrelevantes

public class PrayerControl extends LinearLayout { 


protected PrayerTimeLabel prayerTimeButton; 

protected String prayerName; 
protected static int counter=0; 


public PrayerControl(Context context) { 
    super(context); 
    init(context); 
} 

public PrayerControl(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    getXMLAttributes(context, attrs); 
    init(context); 
} 

    protected void getXMLAttributes(Context context, AttributeSet attrs) 
{ 
    TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.PrayerControl); 

    prayerName = a.getString(R.styleable.PrayerControl_name); 
    dayHalf = a.getString(R.styleable.PrayerControl_dayHalf); 
    hours = a.getInteger(R.styleable.PrayerControl_hours, 4); 
    minutes = a.getInteger(R.styleable.PrayerControl_minutes, 30); 

    ltrProgress = a.getInteger(R.styleable.PrayerControl_postNamazInterval, 0); 
    rtlProgress = a.getInteger(R.styleable.PrayerControl_preNamazInterval, 0); 
    intervalMax = a.getInteger(R.styleable.PrayerControl_intervalMax, 30); 


    a.recycle(); 

} 

protected void init(Context context) 
{ 
    counter++; 
    parentActivity = context; 
    this.setOrientation(LinearLayout.HORIZONTAL); 
    this.setId(counter);  

    prayerTimeButtonStyle = R.style.Button_PrayerTimeButton; 
    initializePrayerTimeButton(); 

} 


protected void initializePrayerTimeButton() 
{ 
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
      LinearLayout.LayoutParams.WRAP_CONTENT, 
      40);   
    params.gravity = Gravity.CENTER; 
    //params.weight = 1.0f; 

    prayerTimeButton = new PrayerTimeLabel(parentActivity,prayerTimeButtonStyle,this); 
    prayerTimeButton.setTime(hours, minutes, dayHalf,false); 

    prayerTimeButton.setLayoutParams(params); 
    this.addView(prayerTimeButton); 
} 

} 
+0

¿Qué significa getxmlAttributes? – Ronnie

+0

he actualizado el código para incluir esa función. Simplemente lee el valor de los elementos en el archivo attr.xml. – sadaf

Respuesta

0

Usted debe hacer en su constructor una llamada al constructor de super(context,attrs,defStyle), que se aplicará el defStyle a su View.

Sin embargo, no puede cambiar el style dinámicamente.

+0

Lo estoy haciendo en la siguiente línea super (context, null, R.style.Button_PrayerTimeButton); en el segundo constructor. ¿Puedes por favor señalar qué está mal con este código? – sadaf

+0

¿También puedo ver el código donde agrega esas vistas personalizadas a un diseño? –

+0

En realidad, este botón personalizado es parte de otro control personalizado que luego se agrega al diseño. Es por eso que quiero aplicar estilos usando constructor y no usando XML. Permítanme actualizar la pregunta para agregar código allí ... – sadaf

3

Ésta es una vieja respuesta: Tengo un -1 hace un par de minutos y aquí está la

NUEVA SOLUCIÓN:

La idea básica consiste en pasar un atributo al constructor . Compruebe este enlace para obtener la solución completa: Applying style to views dynamically in java code

antigua solución (no funciona):

Añadir estos constructores a su clase:

public StyledButton(Context context) { 
    super(context, null, R.style.Button_PrayerTimeButton); 
//... whatever 
} 

public StyledButton(Context context, AttributeSet attrs) { 
    super(context, attrs, R.style.Button_PrayerTimeButton); 
//... whatever 
} 

public StyledButton(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, R.style.Button_PrayerTimeButton); 
//... whatever 
} 
+0

Agregué estos constructores pero no uso :( – sadaf

+0

+1 en el comentario anterior, esto tampoco me funciona – adstro

+0

@adstro gracias por el -1, acabo de ver esto y la respuesta actualizada –

3

Por qué no usar setTextAppearance(Context context, int resid);. Le permite configurar el color, el tamaño, el estilo, el color de la sugerencia y el color de resaltado del texto.

En PrayerTimeLabel clase,

private void init(final Context context, PrayerControl parent, int defStyle) 
{   
    setTextAppearance(context, R.style.Button_PrayerTimeButton); 
    ... 
} 

Para más información ver este post: setTextAppearance through code referencing custom attribute

+0

No es solo textView, textview es el más simple de todos por eso he pegado el código para la vista de texto. Tengo otros controles personalizados que heredan de SeekBar y otros controles de Android. Tengo problemas para configurar los estilos para todos ellos. – sadaf

0

El informe de error que enlazar a los estados:

Además, al crear dinámicamente elementos en ejecución -tiempo esto significa que no puedes simplemente aplicar un estilo en el código. Es necesario crear un diseño de XML independiente de la vista que se está construyendo, y inflarlo [...]

Con esto en mente, una solución podría tener este aspecto:

Crear un diseño xml para su botón - llamémoslo prayertimebutton.xml:

<Button android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textColor="#FFFF00" 
     //...etc 
/> 

Luego, en el método initializePrayerTimeButton en su clase PrayerControl, inflar y agregar el botón PrayerTimeLabel a la PrayerControl diseño:

//Retrieve a LayoutInflater instance that is hooked up to the current context 
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
//The LayoutInflater instantiates the layout file into a PrayerTimeLabel object 
PrayerTimeLabel button = (PrayerTimeLabel)inflater.inflate(R.layout.prayertimebutton, this, false); 
//add the PrayerTimeLabel to the PrayerControl 
this.addView(button); 

Tenga en cuenta que el segundo parámetro de LayoutInflater.inflate() es una referencia a la Vista principal (Grupo).

La respuesta a continuación de adamp, un ingeniero de Android framework en Google, analiza este enfoque con más detalle.

Why so complex to set style from code in Android

+0

Sí, lo leí pero no quiero usar archivos de diseño XML. Tiene que hacerse usando constructores. Este problema fue reportado en 2010 , Estoy sorprendido de que no haya actualizaciones para este problema. – sadaf

+0

¿Puedo preguntar por qué tienes que usar constructores? Según tengo entendido, necesita crear una instancia del botón dinámicamente con su propio estilo y agregarlo dinámicamente a un diseño, lo que la solución en mi respuesta hace posible. Desde el informe de error aparece usando constructores para pasar el estilo es un callejón sin salida. De hecho, es sorprendente que no haya actualizado a esto. –

+0

porque tengo alrededor de 15 controles personalizados e inflar tantos archivos XML no es bueno en términos de recursos, así que pensé que podría haber alguien que haya encontrado una solución para este problema, pero parece que estaba equivocado :( – sadaf

Cuestiones relacionadas