以编程方式获取主题属性

5
如何通过编程方式获取主题属性的值?
例如:
主题:
<style name="Theme">
    ... truncated ....
    <item name="textAppearanceLarge">@android:style/TextAppearance.Large</item>
</style>

代码:

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

编辑:太多的答案没有解决问题。


这段话是指有太多与问题无关的答案,需要更多的解决方案来解决问题。

一个类似的问题在这里得到了解答:https://dev59.com/omsz5IYBdhLWcg3wcXXF - Oderik
可能是android get textappearance runtime的重复问题。 - fho
3个回答

6
使用此函数:
myView.setTextAppearance(Context context, int resid)
//Sets the text color, size, style, hint color, and highlight color from the specified TextAppearance resource.

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

从TextView.java文件中,以上函数所做的事情如下:

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

这是另一种完成此操作的方法。请确保回收外表(TypedArray对象)。希望这能帮到您!

离题了,但在这种情况下,resid会是什么?就像R.attrs.bleh一样的意思。 - user123321
根据您的问题,应该使用R.style.textAppearanceLarge。否则,您也可以直接使用android.R.style.TextAppearance.Large。 - rDroid
酷。你有办法获取“R.style.textAppearanceLarge”的字面整数值吗?我想用它做一些花哨的事情。 - user123321
我不知道。但是你可以使用myView.getTextSize()在从主题设置TextAppearance之后获取textSize。 - rDroid
刚刚检查了TextView.java文件。我已经更新了我的答案。 - rDroid
3
你是如何使用“com.android.internal.R.styleable”的?我得到了“package com.android.internal.R不存在”的错误提示。 - Matthew

2
这应该可以解决问题:
int textAppearance = android.R.attr.textAppearanceLarge;
myTextView.setTextAppearance(context, textAppearance);

0
我最终得到了以下代码:
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;
        }
    }

}

使用示例:

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

R.styleable.RangeBar_textAppearance 是我的属性,但你可以通过以下方式访问 Android 属性:

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

我知道这种方法有点像黑客技术,但是不知道还有什么更好的方法 :(


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接