什么时候应该使用Theme.AppCompat和ThemeOverlay.AppCompat?

125

以下是 Theme.AppCompat 类:

Theme.AppCompat
Theme.AppCompat.Light
Theme.AppCompat.Light.DarkActionBar
Theme.AppCompat.NoActionBar
Theme.AppCompat.Light.NoActionBar
Theme.AppCompat.DialogWhenLarge
Theme.AppCompat.Light.DialogWhenLarge
Theme.AppCompat.Dialog
Theme.AppCompat.Light.Dialog
Theme.AppCompat.CompactMenu

以及以下的ThemeOverlay.AppCompat类:

ThemeOverlay.AppCompat
ThemeOverlay.AppCompat.Light
ThemeOverlay.AppCompat.Dark
ThemeOverlay.AppCompat.ActionBar
ThemeOverlay.AppCompat.Dark.ActionBar

为什么要使用ThemeOverlay.AppCompat.light而不是Theme.AppCompat.Light呢?例如,我发现ThemeOverlay定义的属性要少得多--我很想知道ThemeOverlay的预期用途是什么。

2个回答

180

Theme.AppCompat用于为整个应用程序设置全局主题。ThemeOverlay.AppCompat用于覆盖(或"叠加")特定视图的主题,尤其是工具栏。

让我们看一个例子,为什么这是必要的。

带有ActionBar的应用程序主题

ActionBar通常显示在应用程序中。我可以通过设置colorPrimary值来选择它的颜色。但是,更改主题会更改ActionBar上文本的颜色。

<style name="AppTheme" parent="Theme.AppCompat">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

在此输入图片描述

由于我的主色调是深蓝色,因此我应该使用其中一个在操作栏中使用浅色文本颜色的主题,因为黑色文本很难阅读。

隐藏ActionBar并使用工具栏

使用Theme.AppCompat而不是Theme.Material的全部目的是允许旧版本的Android使用我们的Material Design主题。问题在于旧版本的Android不支持ActionBar。因此,文档建议隐藏ActionBar并将工具栏添加到您的布局中。为了隐藏ActionBar,我们必须使用其中一个NoActionBar主题。以下图像显示了带有隐藏ActionBar的工具栏。

在此输入图片描述

但是如果我想要像具有DarkActionBar的Light主题之类的东西怎么办?由于我必须使用NoActionBar,这不是一个选项。

覆盖应用程序主题

这就是ThemeOverlay的作用。我可以在我的Toolbar xml布局中指定Dark ActionBar主题。

<android.support.v7.widget.Toolbar
    ...
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

这最终使我们能够获得我们想要的效果。Dark.ActionBar主题在这种特定场合下覆盖了Light应用程序主题。

enter image description here

  • 应用程序主题:Theme.AppCompat.Light.NoActionBar
  • 工具栏主题:ThemeOverlay.AppCompat.Dark.ActionBar

如果您希望弹出菜单为浅色,则可以添加以下内容:

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

进一步学习

我通过实验和阅读以下文章来学习这个内容。


如何在使用Themeoverlay时使状态栏透明? - gegobyte
我在想如何使用新的MaterialToolbar实现这一点。 - David
@David,我现在主要使用Flutter进行开发,所以我没有关注最新的Android开发动态。如果你找到答案,请随时回来在这里留下评论、编辑我的答案或者添加你自己的答案。 - Suragch

75
根据 AppCompat 的创建者在 Theme vs Style 博客文章 中所述:[ThemeOverlays] 是特殊的主题,它们覆盖了普通的 Theme.Material 主题,并覆盖相关属性使其变成浅色/深色。你也可以看到 ActionBar ThemeOverlay 派生类:ThemeOverlay.Material.Light.ActionBarThemeOverlay.Material.Dark.ActionBar,它们仅应与 Action Bar 一起使用,通过新的 actionBarTheme 属性设置,或直接设置到 Toolbar 上。这些派生类唯一不同的是将 colorControlNormal 更改为 android:textColorPrimary,从而使文本和图标变成不透明的。

1
嗨,Ian,我从 Android 1 的 Beta 时期开始开发 Android 应用,但我真的从来没有完全理解过主题。这总是试错。你、Chet 或者 UI 工具包团队的其他人有没有关于这个问题的好讲座?如果没有,那可能是下一次 I/O 的好主意。 - rekire

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