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 :(