5

How do I get the value of a Theme attribute programmatically?

For example:

Theme:

<style name="Theme">
    ... truncated ....
    <item name="textAppearanceLarge">@android:style/TextAppearance.Large</item>
</style>

Code:

int textSize = ???? // how do I get Theme.textAppearanceLarge? 

EDIT: too many answers that don't address the question.

user123321
  • 12,593
  • 11
  • 52
  • 63
  • A similar question is answered here: http://stackoverflow.com/questions/7896615/android-how-to-get-value-of-an-attribute-in-code – Oderik May 09 '12 at 07:24
  • possible duplicate of [android get textappearance runtime](http://stackoverflow.com/questions/8983629/android-get-textappearance-runtime) – fho Oct 25 '14 at 23:52

3 Answers3

6

use this function :

myView.setTextAppearance(Context context, int resid)
//Sets the text color, size, style, hint color, and highlight color from the specified TextAppearance resource.

see : http://developer.android.com/reference/android/widget/TextView.html#setTextAppearance%28android.content.Context,%20int%29

From TextView.java this is what the above function does:

public void setTextAppearance(Context context, int resid) {
    TypedArray appearance =
        context.obtainStyledAttributes(resid,
                                       com.android.internal.R.styleable.TextAppearance);

    int color;
    ColorStateList colors;
    int ts;

    .
    .
    .
    ts = appearance.getDimensionPixelSize(com.android.internal.R.styleable.
                                          TextAppearance_textSize, 0);
    if (ts != 0) {
        setRawTextSize(ts);
    }

    int typefaceIndex, styleIndex;

    typefaceIndex = appearance.getInt(com.android.internal.R.styleable.
                                      TextAppearance_typeface, -1);
    styleIndex = appearance.getInt(com.android.internal.R.styleable.
                                   TextAppearance_textStyle, -1);

    setTypefaceByIndex(typefaceIndex, styleIndex);
    appearance.recycle();
}

This is another way of doing this. Do make sure you recycle the appearance (TypedArray obect). Hope this helps!

rDroid
  • 4,875
  • 3
  • 25
  • 30
  • off topic, but what would be the resid in this case? meaning like R.attrs.bleh. – user123321 Nov 19 '11 at 07:52
  • it should be R.style.textAppearanceLarge as per your question. Otherise you could also directly use android.R.style.TextAppearance.Large – rDroid Nov 19 '11 at 08:33
  • cool. Do you have the way get the literal int value of "R.style.textAppearanceLarge"? I want to do some fancy things with it. – user123321 Nov 19 '11 at 08:42
  • not that i know of. But surely you can get the textSize after you have set the TextAppearance from theme using myView.getTextSize() – rDroid Nov 19 '11 at 08:51
  • just checked out the TextView.java. I have updated my answer. – rDroid Nov 19 '11 at 09:11
  • 3
    How did you use "com.android.internal.R.styleable" I get "package com.android.internal.R" does not exist. – Matthew Apr 30 '14 at 22:26
2

This should do the trick:

int textAppearance = android.R.attr.textAppearanceLarge;
myTextView.setTextAppearance(context, textAppearance);
James McCracken
  • 15,488
  • 5
  • 54
  • 62
0

I ended up with the following code:

public class TextAppearanceConsts
{
    private static final String LOG_TAG = "TextAppearanceConsts";

    public static final int[] styleable_TextAppearance;
    public static final int styleable_TextAppearance_textColor;
    public static final int styleable_TextAppearance_textSize;
    public static final int styleable_TextAppearance_typeface;
    public static final int styleable_TextAppearance_fontFamily;
    public static final int styleable_TextAppearance_textStyle;

    static {
        // F*ing freaking code
        int ta[] = null, taTc = 0, taTs = 0, taTf = 0, taFf = 0, taTst = 0; 
        try{
            Class<?> clazz = Class.forName("com.android.internal.R$styleable", false, TextAppearanceConsts.class.getClassLoader());
            ta = (int[])clazz.getField("TextAppearance").get(null);
            taTc = getField(clazz, "TextAppearance_textColor");
            taTs = getField(clazz, "TextAppearance_textSize");
            taTf = getField(clazz, "TextAppearance_typeface");
            taFf = getField(clazz, "TextAppearance_fontFamily");
            taTst = getField(clazz, "TextAppearance_textStyle");
        }catch(Exception e){
            Log.e(LOG_TAG, "Failed to load styleable_TextAppearance", e);
        }
        styleable_TextAppearance = ta;
        styleable_TextAppearance_textColor = taTc;
        styleable_TextAppearance_textSize = taTs;
        styleable_TextAppearance_typeface = taTf;
        styleable_TextAppearance_fontFamily = taFf;
        styleable_TextAppearance_textStyle = taTst;
    }

    private static int getField(Class<?> clazz, String fieldName)
    throws IllegalAccessException
    {
        try{
            return clazz.getField(fieldName).getInt(null);
        }catch(NoSuchFieldException nsfe){
            Log.e(LOG_TAG, nsfe.toString());
            return -1;
        }
    }

}

Usage example:

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RangeBar, 0, 0);
TypedArray appearance = null;
int ap = ta.getResourceId(R.styleable.RangeBar_textAppearance, -1);
if (ap != -1) {
    appearance = context.getTheme().obtainStyledAttributes(ap, TextAppearanceConsts.styleable_TextAppearance);
    int n = appearance.getIndexCount();
    for (int i = 0; i < n; i++) {
        int attr = appearance.getIndex(i);

        if (attr == TextAppearanceConsts.styleable_TextAppearance_textColor){
            mTextColor = appearance.getColorStateList(attr);
        } else if (attr == TextAppearanceConsts.styleable_TextAppearance_textSize){
            mTextSize = appearance.getDimensionPixelSize(attr, mTextSize);
        } else if (attr == TextAppearanceConsts.styleable_TextAppearance_typeface){
            mTypefaceIndex = appearance.getInt(attr, -1);
        } else if (attr == TextAppearanceConsts.styleable_TextAppearance_fontFamily){
            mFontFamily = appearance.getString(attr);
        } else if (attr == TextAppearanceConsts.styleable_TextAppearance_textStyle){
            mFontStyleIndex = appearance.getInt(attr, -1);
        } else {
            ....
        }
    }
    appearance.recycle();
}

The R.styleable.RangeBar_textAppearance is my attribute, but you can access Android attributes this way:

final static String ANDROID_NS = "http://schemas.android.com/apk/res/android";
final int textAppearanceResId = attrs.getAttributeResourceValue(ANDROID_NS, "textAppearance", 0);
....
int ap = ta.getResourceId(textAppearanceResId, -1);

I know the method is some kind of hacking, but don't know any other better one :(

Boguś
  • 150
  • 3
  • 11