Android: как получить значение атрибута в коде?

84

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

TypedValue typedValue = new TypedValue(); 
((Activity)context).getTheme().resolveAttribute(android.R.attr.textAppearanceLarge, typedValue, true);
ab11
источник

Ответы:

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 05
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

Или в котлине:

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
Али Багери
источник