为一个主题覆盖 Android 自定义样式的背景,但不覆盖另一个主题

Override Android background in custom style for one theme but not another

我正在为我的 Android 应用程序使用两个主题,AppThemeAppThemeDark。我在主题定义中为每个按钮设置了自定义按钮样式:

<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:buttonStyle">@style/ButtonStyle</item>
    ...
</style>

<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
    ...
    <item name="android:buttonStyle">@style/ButtonStyleDark</item>
    ...
</style>

<!-- Button styles -->
<style name="ButtonStyle" parent="@style/Widget.AppCompat.Button">
    <item name="android:ellipsize">end</item>
    <item name="android:maxLines">2</item>
</style>

<style name="ButtonStyleDark" parent="ButtonStyle">
    <item name="android:background">@drawable/gray_button_bg</item>
</style>

请注意,我的 AppTheme 按钮 ButtonStyle 不会覆盖 Widget.AppCompat.Button 的背景,但 AppThemeDark 的按钮样式继承了 ButtonStyle 并更改了背景。

现在,我想用特殊按钮的新自定义样式扩展 buttonStyle,例如PrimaryButton。在 AppTheme 案例中,我不想更改按钮的背景。在 AppThemeDark 案例中,我 想要更改按钮的背景。

我想定义 PrimaryButton 并让它继承背景(在 AppTheme 的情况下)或使用新背景 (AppThemeDark)。像这样:

<style name="PrimaryButton">
    <item name="android:background">?attr/drawablePrimaryButtonBackground</item>
</style>

但据我所知,无法将 AppThemeDark 中的属性定义为新的可绘制对象并将 AppTheme 定义为 "inherit from parent"。设置为透明显然会使AppTheme中的按钮背景透明。

我唯一的选择是找出 Widget.AppCompat.Button 中背景使用的可绘制对象并在本地定义它吗?

回答我自己的问题...

  1. 你可以挖掘私有Android资源,使用本地副本保留后台。不过,这会将您锁定在一个特定的 Android 版本的可绘制对象中(除非您复制多个版本)。
  2. 如果您的两个主题之间的样式差异足以保证,您可以将整个样式设置为属性:

attrs.xml:

<attr name="stylePrimaryButton" format="reference" />

styles.xml:

<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="stylePrimaryButton">@style/PrimaryButton</item>
    ...
</style>

<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
    ...
    <item name="stylePrimaryButton">@style/PrimaryButtonDark</item>
    ...
</style>

<!-- Primary button styles -->
<style name="PrimaryButton">
    <!-- no need to override anything -->
</style>

<style name="PrimaryButtonDark">
    <item name="android:background">@drawable/dark_background</item>
</style>

layout.xml:

    <Button style="?attr/stylePrimaryButton"
    ...