Android使用自定义主题修改样式属性

Android Use custom themes to modify style attributes

我想创建两个主题,GrayTheme 和 RedTheme,它们修改一个样式属性。例如这是我的两个主题,默认字体颜色是白色,这对两个主题都很好:

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
</style>

<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
</style>

但我有一种用于 Header TextView 的样式。如果我使用的是 RedTheme,我希望样式 HeaderFont 的 textColor 为红色,如果是 GrayTheme,我希望 HeaderFont textColor 为灰色,而无需修改个人 xml 访问此 Header 字体样式的文件。

<style name="HeaderFont" parent="@android:style/TextAppearance.Medium">
    <item name="android:textColor">@color/gray</item>
</style>

我一直在寻找一个优雅的解决方案,但一直找不到任何东西。想法?

在多次寻找干净的解决方案失败后,我终于找到了一个完美的答案。

我创建了一个自定义属性 headerFontColor 并将其添加到 /res/values/attrs。xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="headerFontColor" format="reference|color" />
</resources>

接下来,在 HeaderFont 的样式中,我添加了将 textColor 更新为新的自定义属性 (headerFontColor) 而不是特定的颜色

<style name="HeaderFont" parent="@android:style/TextAppearance.Medium">
    <item name="android:textColor">?headerFontColor</item>
</style>

现在,我可以根据主题简单地设置 headerFontColor 属性

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
    <item name="headerFontColor">@color/red</item>
</style>
<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
    <item name="headerFontColor">@color/gray</item>
</style>

执行此操作后,所有使用 HeaderFont 样式的 TextView 都会更新为 headerFontColor,只需切换 Theme

这个解决方案指导了我:Setting a color based on theme

我使用了来自 google 的 iosched 项目的引用。

在 res/values/

中创建了一个 attrs.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="Theme">
    <attr name="headerFontColor" format="color" />
  </declare-styleable>
</resources>

然后在themes.xml

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
  <item name="headerFontColor">@color/red</item>
</style>

<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
  <item name="headerFontColor">@color/gray</item>
</style>