Android: jak uzyskać wartość atrybutu w kodzie?


83

Chciałbym pobrać wartość int textApperanceLarge w kodzie. Uważam, że poniższy kod zmierza w dobrym kierunku, ale nie mogę dowiedzieć się, jak wyodrębnić wartość int z TypedValue.

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

Podobnie jak w przypadku
uzyskiwania

Odpowiedzi:


128

Twój kod pobiera tylko identyfikator zasobu stylu, na który wskazuje atrybut textAppearanceLarge , a mianowicie TextAppearance.Large, jak wskazuje Reno.

Aby uzyskać wartość atrybutu textSize ze stylu, po prostu dodaj ten kod:

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

Teraz textSize będzie rozmiarem tekstu w pikselach w stylu, na który wskazuje textApperanceLarge , lub -1, jeśli nie został ustawiony. Zakładamy, że typedValue.type był typem TYPE_REFERENCE na początku, więc powinieneś to najpierw sprawdzić.

Numer 16973890 pochodzi z faktu, że jest to identyfikator zasobu TextAppearance.Large


6
działa jak marzenie. tylko dlaczego to musi być tak skomplikowane… czy nie ma już mniej niejasnego podejścia, sześć lat później?
Cee McSharpface

55

Za pomocą

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

Dla ciągu:

typedValue.string
typedValue.coerceToString()

W przypadku innych danych:

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

W twoim przypadku to, co zwraca, jest z TYPE_REFERENCE.

Wiem, że powinno wskazywać na TextAppearance.Large

Który jest :

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

Podziękowania dla Martina za rozwiązanie tego problemu:

int[] attribute = new int[] { android.R.attr.textSize };
TypedArray array = context.obtainStyledAttributes(typedValue.resourceId, attribute);
int textSize = array.getDimensionPixelSize(0, -1);

1
TypedValue.data oblicza jako: 16973890. To nie wydaje się poprawne dla rozmiaru tekstu.
ab11

@ ab11 to nie jest rozmiar tekstu. Jest to liczba całkowita zasobu wymiarów.
Sevastyan Savanyuk

9

Lub w Kotlinie:

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

4

Wygląda na to, że jest to śledztwo w sprawie odpowiedzi @ user3121370. Spłonęli. : O

Jeśli potrzebujesz tylko wymiaru, na przykład wypełnienia, minHeight (mój przypadek to: android.R.attr.listPreferredItemPaddingStart). Możesz to zrobić:

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

Tak jak to zrobiło pytanie, a potem:

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

Podobnie jak usunięta odpowiedź. Umożliwi to pominięcie obsługi rozmiarów urządzeń w pikselach, ponieważ używa domyślnych danych dotyczących urządzeń. Zwrot będzie typu float i należy rzutować na int.

Uważaj na typ, który próbujesz uzyskać, na przykład resourceId.


1

to jest mój kod.

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.