什么时候应该使用 Theme.AppCompat 与 ThemeOverlay.AppCompat?
Posted
技术标签:
【中文标题】什么时候应该使用 Theme.AppCompat 与 ThemeOverlay.AppCompat?【英文标题】:When should one use Theme.AppCompat vs ThemeOverlay.AppCompat? 【发布时间】:2015-01-30 01:13:36 【问题描述】:有以下 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 的预期用例是什么。
【问题讨论】:
【参考方案1】: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。因此,documentation 建议隐藏 ActionBar 并将 Toolbar 添加到您的布局中。要隐藏 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 应用主题。
应用主题:Theme.AppCompat.Light.NoActionBar
工具栏主题:ThemeOverlay.AppCompat.Dark.ActionBar
如果您希望弹出菜单更轻,可以添加:
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
进一步研究
我通过实验和阅读以下文章了解到这一点。
Setting Up the App Bar Use android:theme and ThemeOverlay to theme specific Views and their descendents Theming with AppCompat Use colorPrimary to colorize your App Bar Theme vs Style【讨论】:
使用Themeoverlay时如何让状态栏透明? 我想知道如何使用新的 MaterialToolbar 来实现这一点 @David,我现在主要使用 Flutter,所以我没有跟上新的 Android 开发。如果您找到答案,请随时返回此处发表评论、编辑我的答案或添加您自己的答案。【参考方案2】:根据 AppCompat 的创建者Theme vs Style blog post:
[ThemeOverlays] 是覆盖普通 Theme.Material 主题的特殊主题,覆盖相关属性以使它们变亮/变暗。
ThemeOverlay + ActionBar
目光敏锐的你也会看到 ActionBar ThemeOverlay 衍生产品:
ThemeOverlay.Material.Light.ActionBar
ThemeOverlay.Material.Dark.ActionBar
这些只能通过新的
actionBarTheme
属性与操作栏一起使用,或者直接在您的工具栏上设置。
这些目前与父母不同的唯一事情是他们将
colorControlNormal
更改为android:textColorPrimary
,从而使任何文本和图标不透明。
【讨论】:
嗨,Ian,我从 Android 1 的 Beta 时代就开始为 Android 开发,但我真的从来没有完全理解过主题。它总是跟踪和错误。您、Chet 或 UI Toolkit 团队的任何其他人是否就此进行了很好的讨论?如果不是,那可能是下一个 I/O 的好主意。以上是关于什么时候应该使用 Theme.AppCompat 与 ThemeOverlay.AppCompat?的主要内容,如果未能解决你的问题,请参考以下文章
弹出AlertDialog的时候报You need to use a Theme.AppCompat theme (or descendant) with this activity错误
如何使用主题和 Theme.AppCompat.DayNight 更改操作栏中的文本颜色
Android : Theme.Holo VS Theme.AppCompat
ActionBarCompat: java.lang.IllegalStateException: 你需要使用 Theme.AppCompat