如何从styles.xml中以编程方式检索样式属性


81

目前,我正在使用WebView或TextView在我的一个应用程序中显示一些来自Web服务的动态数据。如果数据包含纯文本,它将使用TextView并应用来自styles.xml的样式。如果数据包含HTML(主要是文本和图像),则使用WebView。

但是,此WebView是未设置样式的。因此,它看起来与通常的TextView有很大不同。我已经读到,只需在数据中直接插入一些HTML,就可以在WebView中设置文本样式。这听起来很容易,但是我想将Styles.xml中的数据用作此HTML中所需的值,因此如果更改样式,则无需在两个位置更改颜色等。

那么,我该怎么做呢?我已经进行了广泛的搜索,但没有找到从您的styles.xml中实际检索不同样式属性的方法。我是否在这里缺少某些东西,还是真的无法检索这些值?

我尝试从中获取数据的样式如下:

<style name="font4">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">#E3691B</item>
    <item name="android:paddingLeft">5dp</item>
    <item name="android:paddingRight">10dp</item>
    <item name="android:layout_marginTop">10dp</item>
    <item name="android:textStyle">bold</item>
</style>

我主要对textSize和textColor感兴趣。


您为什么不只解析XML(例如Android的SAX解析器)?
m0skit0 2012年

Answers:


174

可以通过styles.xml编程方式检索自定义样式。

在中定义一些任意样式styles.xml

<style name="MyCustomStyle">
    <item name="android:textColor">#efefef</item>
    <item name="android:background">#ffffff</item>
    <item name="android:text">This is my text</item>
</style>

现在,检索这样的样式

// The attributes you want retrieved
int[] attrs = {android.R.attr.textColor, android.R.attr.background, android.R.attr.text};

// Parse MyCustomStyle, using Context.obtainStyledAttributes()
TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, attrs);

// Fetch the text from your style like this.     
String text = ta.getString(2);

// Fetching the colors defined in your style
int textColor = ta.getColor(0, Color.BLACK);
int backgroundColor = ta.getColor(1, Color.BLACK);

// Do some logging to see if we have retrieved correct values
Log.i("Retrieved text:", text);
Log.i("Retrieved textColor as hex:", Integer.toHexString(textColor));
Log.i("Retrieved background as hex:", Integer.toHexString(backgroundColor));

// OH, and don't forget to recycle the TypedArray
ta.recycle()

很棒的同事。在被告知(并大量阅读)无法完成之后,您完美地展示了它可以。尝试一下,我便可以从样式中获得字体颜色。还不能完全获得textsize,但是我会弄清楚的。我可以发送赏金时立即获得100分(从现在开始18个小时)。非常感谢!
Sander van't Veer 2012年

4
是否还可以在运行时更改样式中定义的值?
ekjyot

如果我想更改检索到的属性的颜色怎么办?是否喜欢在此代码中动态更改背景或文本颜色?
MSIslam 2014年

2
我对此行有疑问:“ TypedArray ta = getStyledAttributes(R.style.MyCustomStyle,attrs);”,Android Studio告诉我,它期望可样式化类型的资源,并且我看不到任何方法来抑制注释中的注释支持库。我假设gainStyledAttributes具有@ResStyleable注解,这使我无法通过int传递样式。有任何想法吗?
本·皮尔森

1
@BenPearson-我遇到了与尝试获取textSize属性相同的问题。PrivatMamtora的答案有效,应该被接受。
thecoolmacdude 2014年

52

@Ole给出的答案似乎在使用某些属性(例如shadowColor,shadowDx,shadowDy,shadowRadius)时中断(我发现的只有少数,可能还有更多)

我不知道为什么会发生这个问题,这是我在这里问的,但是@AntoineMarques编码风格似乎可以解决这个问题。

要使此属性与任何属性一起使用,将类似于以下内容


首先,定义一个样式以包含资源ID,如下所示

attrs.xml

<resources>     
    <declare-styleable name="MyStyle" >
        <attr name="android:textColor" />
        <attr name="android:background" />
        <attr name="android:text" />
    </declare-styleable>
</resources>

然后在代码中,您将执行此操作以获取文本。

TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, R.styleable.MyStyle);  
String text = ta.getString(R.styleable.MyStyle_android_text);

使用此方法的优点是,您是按名称而不是索引来检索值。


3
这应该是可接受的答案,因为Ole的答案为我生成了“可样式化的预期资源”警告。
thecoolmacdude 2014年

1
适用于我,但是对于Android Studio,我需要在前缀上添加一个@SuppressWarnings("ResourceType")
eruve

2
这个答案应该是公认的。这对我所有的属性都是有效的,而投票最多的一项浪费了我很多时间。
jerry

1
感谢强大的海豚为您提供的解决方案。可接受的答案给我带来了诸如背景(使用可绘制时)和文本大小等属性的问题。该解决方案不仅适用于我需要的所有属性,而且还提供了更简洁的代码。
Marius P.

2
R.style.MyCustomStyle应该是什么?
janosch

1

Ole和PrivatMamtora的答案对我来说效果不佳,但确实如此。

假设我想以编程方式阅读此样式:

<style name="Footnote">
    <item name="android:fontFamily">@font/some_font</item>
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">@color/black</item>
</style>

我可以这样做:

fun getTextColorSizeAndFontFromStyle(
    context: Context, 
    textAppearanceResource: Int // Can be any style in styles.xml like R.style.Footnote
) {
    val typedArray = context.obtainStyledAttributes(
        textAppearanceResource,
        R.styleable.TextAppearance // These are added to your project automatically.
    )
    val textColor = typedArray.getColorStateList(
        R.styleable.TextAppearance_android_textColor
    )
    val textSize = typedArray.getDimensionPixelSize(
        R.styleable.TextAppearance_android_textSize
    )

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val typeface = typedArray.getFont(R.styleable.TextAppearance_android_fontFamily)

        // Do something with the typeface...

    } else {
        val fontFamily = typedArray.getString(R.styleable.TextAppearance_fontFamily)
            ?: when (typedArray.getInt(R.styleable.TextAppearance_android_typeface, 0)) {
                1 -> "sans"
                2 -> "serif"
                3 -> "monospace"
                else -> null
            }

        // Do something with the fontFamily...
    }
    typedArray.recycle()
}

我从Android的TextAppearanceSpan类中获得了一些启发,您可以在这里找到它:https ://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/style/TextAppearanceSpan.java


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.