Android: ¿cómo obtener el valor de un atributo en el código?

82

Me gustaría recuperar el valor int de textApperanceLarge en el código. Creo que el siguiente código va en la dirección correcta, pero no puedo averiguar cómo extraer el valor int del TypedValue.

TypedValue typedValue = new TypedValue(); 
((Activity)context).getTheme().resolveAttribute(android.R.attr.textAppearanceLarge, typedValue, true);
ab11
fuente

Respuestas:

127

Su código solo obtiene el ID de recurso del estilo al que apunta el atributo textAppearanceLarge , a saber, TextAppearance.Large como señala Reno.

Para obtener el valor del atributo textSize del estilo, simplemente agregue este código:

int[] textSizeAttr = new int[] { android.R.attr.textSize };
int indexOfAttrTextSize = 0;
TypedArray a = context.obtainStyledAttributes(typedValue.data, textSizeAttr);
int textSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
a.recycle();

Ahora textSize será el tamaño del texto en píxeles del estilo al que apunta textApperanceLarge , o -1 si no se estableció. Esto es asumiendo que typedValue.type era del tipo TYPE_REFERENCE para empezar, por lo que debe verificar eso primero.

El número 16973890 proviene del hecho de que es el ID de recurso de TextAppearance.

Martin Nordholts
fuente
6
Funciona de maravilla. ¿Por qué tiene que ser tan complicado ... no hay un enfoque menos oscuro ahora, seis años después?
Cee McSharpface
54

Utilizando

  TypedValue typedValue = new TypedValue(); 
  ((Activity)context).getTheme().resolveAttribute(android.R.attr.textAppearanceLarge, typedValue, true);

Para la cuerda:

typedValue.string
typedValue.coerceToString()

Para otros datos:

typedValue.resourceId
typedValue.data  // (int) based on the type

En su caso lo que devuelve es del TYPE_REFERENCE.

Sé que debería apuntar a TextAppearance.Large

Cual es :

<style name="TextAppearance.Large">
    <item name="android:textSize">22sp</item>
    <item name="android:textStyle">normal</item>
    <item name="android:textColor">?textColorPrimary</item>
</style>

El crédito es para Martin por resolver esto:

int[] attribute = new int[] { android.R.attr.textSize };
TypedArray array = context.obtainStyledAttributes(typedValue.resourceId, attribute);
int textSize = array.getDimensionPixelSize(0, -1);
Reno
fuente
1
typedValue.data se evalúa como: 16973890. Esto no parece correcto, para un tamaño de texto.
ab11
@ ab11 no es el tamaño del texto. Es el número entero del recurso de dimensiones.
Sevastyan Savanyuk
9

O en kotlin:

fun Context.dimensionFromAttribute(attribute: Int): Int {
    val attributes = obtainStyledAttributes(intArrayOf(attribute))
    val dimension = attributes.getDimensionPixelSize(0, 0)
    attributes.recycle()
    return dimension
}
Renetik
fuente
4

Parece ser una inquisición sobre la respuesta de @ user3121370. Se quemaron. : O

Si solo necesita obtener una dimensión, como un relleno, minHeight (mi caso fue: android.R.attr.listPreferredItemPaddingStart). Tu puedes hacer:

TypedValue typedValue = new TypedValue(); 
((Activity)context).getTheme().resolveAttribute(android.R.attr.listPreferredItemPaddingStart, typedValue, true);

Al igual que hizo la pregunta, y luego:

final DisplayMetrics metrics = new android.util.DisplayMetrics();
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
int myPaddingStart = typedValue.getDimension( metrics );

Al igual que la respuesta eliminada. Esto le permitirá omitir el manejo de tamaños de píxeles del dispositivo, ya que utiliza la métrica predeterminada del dispositivo. El retorno será flotante y debes convertirlo en int.

Tenga cuidado con el tipo que está intentando obtener, como resourceId.

Ratata Tata
fuente
1

este es mi codigo.

public static int getAttributeSize(int themeId,int attrId, int attrNameId)
{
    TypedValue typedValue = new TypedValue();
    Context ctx = new ContextThemeWrapper(getBaseContext(), themeId);

    ctx.getTheme().resolveAttribute(attrId, typedValue, true);

    int[] attributes = new int[] {attrNameId};
    int index = 0;
    TypedArray array = ctx.obtainStyledAttributes(typedValue.data, attributes);
    int res = array.getDimensionPixelSize(index, 0);
    array.recycle();
    return res;
} 

// getAttributeSize(theme, android.R.attr.textAppearanceLarge, android.R.attr.textSize)   ==>  return android:textSize
Ali Bagheri
fuente