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

San*_*eer 74 xml android styles

目前我正在使用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>
Run Code Online (Sandbox Code Playgroud)

我主要对textSize和textColor感兴趣.

Ole*_*Ole 158

可以通过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>
Run Code Online (Sandbox Code Playgroud)

现在,检索这样的样式

// 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()
Run Code Online (Sandbox Code Playgroud)

  • 是否也可以更改运行时样式中定义的值? (4认同)
  • 我对这一行有一个问题:'TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle,attrs);',Android工作室告诉我它期望资源类型为styleable,我看不出任何方法来抑制注释中的注释支持库.我假设obtainStyledAttributes有一个@ResStyleable注释,它阻止我将样式作为int传递.有任何想法吗? (2认同)
  • @BenPearson - 我遇到了与您尝试获取 textSize 属性相同的问题。PrivatMamtora 的答案有效,应该被接受。 (2认同)

Pri*_*ora 43

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

我不知道为什么会出现这个问题,我在这里问,但@AntoineMarques编码风格似乎解决了这个问题.

为了使这个工作与任何属性,它将是这样的


首先,定义一个stylable来包含资源ID,就像这样

attrs.xml

<resources>     
    <declare-styleable name="MyStyle" >
        <attr name="android:textColor" />
        <attr name="android:background" />
        <attr name="android:text" />
    </declare-styleable>
</resources>
Run Code Online (Sandbox Code Playgroud)

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

TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, R.styleable.MyStyle);  
String text = ta.getString(R.styleable.MyStyle_android_text);
Run Code Online (Sandbox Code Playgroud)

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

  • 这应该是公认的答案,因为Ole的答案为我生成了"类型风格的预期资源"警告. (3认同)
  • 这个答案应该是公认的答案.它适用于我的所有属性,而投票最多的人浪费了我很多时间. (2认同)
  • R.style.MyCustomStyle 应该是什么? (2认同)

Bre*_* K. 5

我无法让早期的解决方案发挥作用。

我的风格是:

<style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
    <item name="android:textSize">12sp</item>
    <item name="android:fontFamily">sans-serif</item>
    <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
    <item name="android:paddingBottom">0dp</item>
</style>
Run Code Online (Sandbox Code Playgroud)

android.R.attr.textSize 的 acquireStyledAttributes() 给出“12sp”的字符串结果,然后我必须解析它。对于 android.R.attr.textColor,它给出了资源文件 XML 名称。这实在是太麻烦了。

相反,我找到了一种使用 ContextThemeWrapper 的简单方法。

TextView sample = new TextView(new ContextThemeWrapper(getContext(), R.style.Widget_TextView_NumPadKey_Klondike), null, 0);
Run Code Online (Sandbox Code Playgroud)

这给了我一个完整样式的 TextView 来查询我想要的任何内容。例如:

float textSize = sample.getTextSize();
Run Code Online (Sandbox Code Playgroud)