我该如何通过编程应用样式?

23

我有两种风格分别叫做红色和绿色,并且我有一个if语句来确定应该应用哪一个,但是我不知道如何从Java中实际应用样式。


7
请在提问之前先搜索,确保您的问题没有被解决过。例如:https://dev59.com/mHI-5IYBdhLWcg3wF0Uc,https://dev59.com/_3A75IYBdhLWcg3wg5fs等。 - Pedro Loureiro
请查看此链接:http://www.anddev.org/view-layout-resource-problems-f27/how-to-programmatically-set-button-style-t8656.html 这应该会有所帮助。 - Rohit Mandiwal
4个回答

36

对于这个问题,没有单一的解决方案,但对我的使用情况有效。问题在于 'View(context, attrs, defStyle)' 构造函数并不是指一个实际的样式,它需要一个属性。因此,我们将会:

  1. 定义一个属性
  2. 创建您想要使用的样式
  3. 将该属性的风格应用于我们的主题
  4. 使用该属性创建新的视图实例

在 'res/values/attrs.xml' 中,定义一个新的属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="customTextViewStyle" format="reference"/>
    ...
</resources>    

我将在'res/values/styles.xml'中创建我想要用于自定义TextView的样式。

<style name="CustomTextView">
    <item name="android:textSize">18sp</item>
    <item name="android:textColor">@color/white</item>
    <item name="android:paddingLeft">14dp</item>
</style>

在'res/values/themes.xml'或'res/values/styles.xml'中,修改您的应用程序/活动主题并添加以下样式:

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <item name="customTextViewStyle">@style/CustomTextView</item>
    </style>
    ... 
</resources>

最后,在您的自定义 TextView 中,现在可以使用带有属性的构造函数,并且它将接收您的样式。在这里,不再是始终

public class CustomTextView extends TextView {

    public CustomTextView(Context context, int styleAttribute) {
        super(context, null, styleAttribute);
    }

    // You could also just apply your default style if none is given
    public CustomTextView(Context context) {
        super(context, null, R.attr.customTextViewStyle);
    }
}

有了这些组件,现在您可以使用 if/else 语句在运行时生成新视图,并选择您喜欢的样式。

CustomTextView ctv;
if(useCustomStyles == true){
    ctv = new CustomTextView(context, R.attr.customTextViewStyle);
}else{
    ctv = new CustomTextView(context, R.attr.someOtherStyle);
}

值得注意的是,我在不同的变量和不同的地方反复使用了customTextView,但是视图的名称与样式、属性或任何其他内容是否匹配并不是必需的。此外,这种技术应该适用于任何自定义视图,而不仅仅是TextView。


1
对我来说,使用<item name="@attr/customTextViewStyle">没有起作用,我不得不删除@attr才能使其正常工作,所以只需使用<item name="customTextViewStyle"> - petroni

12

可以使用 setTextAppearance(context, resid) 方法对TextView进行编程式样式应用。(样式的resId可以在R.style.YourStyleName中找到)


7
我发现只有在Java内部创建View时才能这样做。如果事先在XML中定义,就无法动态更改样式。

13
这个回答如何回答你自己的问题? - Quality Catalyst
这不是正确的答案。即使您在XML中设置了可绘制对象,也可以通过编程方式覆盖它。 - mefahimrahman

4
您可以使用全新的Paris库来以编程方式应用样式:
Paris.style(yourView).apply(condition ? R.style.Green : R.style.Red);

唯一的注意点是,并非所有属性都被支持(但许多属性都支持,并且可以通过为该库做出贡献来轻松添加支持)。

免责声明:我是该库的原始作者。


这应该被标记为答案,迄今为止最好的! - Edouard Brèthes
它可能只是一个库,但它确实解决了问题。为什么没有标记为答案? - Honza Rössler

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