Android: Wie erhalte ich den Wert eines Attributs im Code?

82

Ich möchte den int-Wert von textApperanceLarge im Code abrufen. Ich glaube, dass der folgende Code in die richtige Richtung geht, kann aber nicht herausfinden, wie der int-Wert aus dem TypedValue extrahiert werden kann.

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

Antworten:

127

Ihr Code erhält nur die Ressourcen-ID des Stils, auf den das Attribut textAppearanceLarge verweist, nämlich TextAppearance.Large, wie Reno hervorhebt .

Fügen Sie einfach den folgenden Code hinzu, um den textSize- Attributwert aus dem Stil abzurufen :

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();

Jetzt ist textSize die Textgröße in Pixel des Stils, auf den textApperanceLarge zeigt, oder -1, wenn es nicht festgelegt wurde. Dies setzt voraus, dass typedValue.type zunächst vom Typ TYPE_REFERENCE war. Überprüfen Sie dies daher zuerst.

Die Nummer 16973890 ergibt sich aus der Tatsache, dass es sich um die Ressourcen-ID von TextAppearance.Large handelt

Martin Nordholts
quelle
6
klappt wunderbar. nur warum muss es so kompliziert sein ... gibt es jetzt, sechs Jahre später, keinen weniger obskuren Ansatz?
Cee McSharpface
51

Verwenden von

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

Für die Zeichenfolge:

typedValue.string
typedValue.coerceToString()

Für andere Daten:

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

In Ihrem Fall ist das, was es zurückgibt, von der TYPE_REFERENCE.

Ich weiß, dass es auf TextAppearance.Large verweisen sollte

Welches ist :

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

Dank geht an Martin für die Lösung dieses Problems:

int[] attribute = new int[] { android.R.attr.textSize };
TypedArray array = context.obtainStyledAttributes(typedValue.resourceId, attribute);
int textSize = array.getDimensionPixelSize(0, -1);
Reno
quelle
1
typedValue.data ergibt: 16973890. Dies scheint für eine Textgröße nicht korrekt zu sein.
ab11
@ ab11 es ist nicht die Textgröße. Es ist die Ganzzahl der Dimensionsressource.
Sevastyan Savanyuk
9

Oder in Kotlin:

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

Es scheint eine Inquisition auf die Antwort des @ user3121370 zu sein. Sie brannten nieder. :Ö

Wenn Sie nur eine Dimension wie eine Auffüllung benötigen, minHeight (mein Fall war: android.R.attr.listPreferredItemPaddingStart). Du kannst tun:

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

Genau wie die Frage und dann:

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

Genau wie die entfernte Antwort. Auf diese Weise können Sie die Pixelgröße des Geräts überspringen, da die Standardgerätemetrik verwendet wird. Die Rückkehr wird float sein, und Sie sollten auf int umwandeln.

Achten Sie auf den Typ, den Sie abrufen möchten, z. B. resourceId.

Ratata Tata
quelle
1

Das ist mein Code.

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
quelle