Android: як отримати значення атрибута в коді?


84

Я хотів би отримати в коді значення int textApperanceLarge. Я вважаю, що наведений нижче код рухається в правильному напрямку, але не можу зрозуміти, як витягнути значення int із TypedValue.

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

Подібно до доступу
Suragch

Відповіді:


129

Ваш код отримує лише ідентифікатор ресурсу стилю, на який вказує атрибут textAppearanceLarge , а саме TextAppearance.Large, як вказує Рено.

Щоб отримати значення атрибута textSize зі стилю, просто додайте цей код:

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

Тепер textSize буде розміром тексту в пікселях стилю, на який вказує textApperanceLarge , або -1, якщо він не встановлений. Це припускає, що typedValue.type для початку мав тип TYPE_REFERENCE, тому спочатку слід перевірити це.

Номер 16973890 походить від того, що це ідентифікатор ресурсу TextAppearance.Large


6
працює як шарм. просто чому це повинно бути настільки складним ... чи є не менш незрозумілий підхід донині, через шість років?
Cee McSharpface

55

Використовуючи

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

Для рядка:

typedValue.string
typedValue.coerceToString()

Для інших даних:

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

У вашому випадку те, що воно повертає, має TYPE_REFERENCE.

Я знаю, що це повинно вказувати на TextAppearance.Large

Який є :

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

За вирішення цього питання заслуговує Мартін:

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

1
typedValue.data має значення: 16973890. Це здається неправильним для розміру тексту.
ab11

@ ab11 це не розмір тексту. Це ціле число ресурсу вимірювань.
Севастян Саванюк

9

Або в kotlin:

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

4

Здається, це інквізиція щодо відповіді @ user3121370. Вони згоріли. : O

Якщо вам просто потрібно отримати розмір, такий як заповнення, minHeight (мій випадок був: android.R.attr.listPreferredItemPaddingStart). Ви можете зробити:

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

Так само, як і запитання, а потім:

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

Так само, як вилучена відповідь. Це дозволить вам пропустити обробку розмірів пікселів пристрою, оскільки він використовує метрику пристрою за замовчуванням. Повернення буде плаваючим, і ви повинні передати int.

Будьте обережні з типом, який ви намагаєтесь отримати, як-от resourceId.


1

це мій код.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.