CAB溢出菜单自定义样式

8

在我的应用程序中,我展示了一个上下文操作栏。因为没有足够的空间容纳所有的动作,一些动作需要通过“溢出菜单”按钮来访问。现在我想要样式化“溢出菜单”并更改它的背景。我的主题继承自Theme.AppCompat,我已经定义了以下这些样式:

<item name="android:popupMenuStyle">@style/PopupMenu</item>
<item name="android:listPopupWindowStyle">@style/PopupMenu</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView</item>

<style name="PopupMenu" parent="Widget.AppCompat.PopupMenu">
    <!--<item name="android:popupBackground">@color/dark_color</item>-->
    <item name="android:textColor">?android:textColorPrimary</item>
    <item name="android:dropDownSelector">?popupItemBackground</item>
</style>

<style name="DropDownListView" parent="Widget.AppCompat.ListView.DropDown">
    <item name="android:listSelector">?popupItemBackground</item>
    <item name="android:divider">@null</item>
    <item name="android:dividerHeight">0dp</item>
</style>

我的应用程序中的其他菜单(操作栏中的溢出菜单和其他菜单)都有风格,但是上下文操作栏的溢出菜单没有。我该怎么办?

你在这方面有进展吗?我在platform_frameworks_base/core/res/res/values/themes.xml中找到了actionModePopupWindowStyle,并在platform_frameworks_base/core/res/res/values/styles.xml中找到了Widget.PopupWindow,但是在我的样式中覆盖它似乎没有效果。 - JDJ
我还没有找到解决方案... - Sandra
@JDJ 我找到了一个解决方案。请看我的答案。 - Sandra
3个回答

2
要更改溢出菜单的背景,您需要覆盖属性 actionOverflowMenuStyle:
<!-- add to your parent style -->
<item name="actionOverflowMenuStyle">@style/LStyled.PopupMenu.OverflowMenu</item>

<style name="LStyled.PopupMenu.OverflowMenu" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
    <!-- 'overlapAnchor' changes position of the popup -->
    <!-- true - popup will be shown over the overflow button -->
    <!-- false - popup will be shown below the overflow button -->
    <item name="overlapAnchor">false</item>
    <item name="android:popupBackground">@drawable/bg_cab_popup</item>
</style>

Drawable bg_cab_popup 可以是任何类型的可绘制对象,但使用9-patch图像更有意义。

如果您需要更改的不仅仅是背景,请在评论中告诉我。


我尝试使用您的解决方案来输入弹出背景的颜色值,但并没有按预期工作。结果是一种双倍的、看起来不正确的背景用于溢出菜单,但确实改变了它。当我尝试使用可绘制资源时,它可以正常工作。但是然后我需要模仿应用程序中其他菜单的背景,这些菜单具有默认形式(我只更改颜色)。我是否也可以在这里以某种方式更改颜色,还是应该查找他们用于菜单背景的Android资源?如果是这种情况,我应该在哪里找到它?谢谢 - Sandra
@Sandra 我还没有尝试过在可绘制对象的位置传递颜色值。问题可能是ColorDrawable(这就是最终转换为颜色值的对象)没有固有的宽度和高度。我大多数情况下使用Photoshop进行图像处理。显而易见的好处是您可以拥有完全自定义的主题。类似于这样的东西:使用9patch的溢出菜单背景 - Vikram

2
我终于找到了解决方案。看起来你需要将以下内容添加到你的主题中:
<item name="actionBarPopupTheme">@style/ThemeOverlay.My</item>

地点:

<style name="ThemeOverlay.My" parent="ThemeOverlay.AppCompat">
    <item name="android:colorBackground">@color/my_theme_background</item>
</style>

colorBackground属性可以使用任何您喜欢的颜色值,并且使用此属性,您可以为上下文操作按钮的溢出菜单设置样式。


0
我假设您正在使用最新的(21.x.x)appcompat-v7库,并采用了新的Toolbar小部件。为了实现您想要的效果,您不需要修改主应用程序主题(除了文本选择操作模式),而是将样式应用于布局中的Toolbar元素(style="@style/Widget.YourApp.Toolbar")。样式定义可能类似于以下内容:
<style name="Widget.YourApp.Toolbar" parent="Widget.AppCompat.Toolbar">
  <item name="android:background">#111</item>
  <item name="android:elevation" tools:ignore="NewApi">8dp</item>
  <item name="theme">@style/ThemeOverlay.YourApp.ActionBar</item>
  <item name="popupTheme">@style/ThemeOverlay.YourApp</item>
</style>

对于你想要实现的功能,popupTheme 是最重要的属性。它指向另一个样式定义,描述了工具栏弹出菜单的外观。

<style name="ThemeOverlay.YourApp" parent="ThemeOverlay.AppCompat">
  <item name="android:colorBackground">#f00</item>
  <item name="android:textColor">#ff0</item>
</style>

重要提示:请注意,您将使用此作为主题而不是样式。当您应用样式时,属性仅设置在指定的一个布局元素上。当您应用主题时,属性会传播到所有子元素。这就是为什么在使用主题时,您永远不会覆盖background(这会导致过度绘制和不希望的外观),而是优先考虑更具体的属性,如windowBackgroundcolorBackground(仅适用于相关顶部元素)。

为了使这个例子完整,我也会包括一个工具栏主题:

<style name="ThemeOverlay.YourApp.ActionBar" parent="ThemeOverlay.AppCompat.ActionBar">
  <!-- these color action bar title and subtitle -->
  <item name="android:textColorPrimary">#00f</item>
  <item name="android:textColorSecondary">#0ff</item>
  <!-- this colors the icons (apply manual tinting for non-appcompat icons programmatically) -->
  <item name="colorControlNormal">#0f0</item>
  <!-- bug in the library - the overflow icon on Lollipop will now respect the above -->
  <item name="android:colorControlNormal" tools:ignore="NewApi">?colorControlNormal</item>
  <!-- these color the text of action items -->
  <item name="actionMenuTextColor">?colorControlNormal</item>
</style>

注意:使用自定义文本颜色时,请使用选择器,并将禁用颜色定义为双倍(如果您正在按钮或菜单中使用颜色,则要这样做)。

编辑

上述解决方案据说不适用于上下文操作栏或操作模式弹出窗口。我发现它由活动主题上定义的以下属性控制:

<item name="actionModePopupWindowStyle">?attr/popupWindowStyle</item>

默认值指向@style/Widget.PopupMenu,其定义如下:

<style name="Widget.PopupWindow">
    <item name="popupBackground">@drawable/editbox_dropdown_background_dark</item>
    <item name="popupAnimationStyle">@style/Animation.PopupWindow</item>
</style>

创建一个基于 Widget.PopupWindow 的自定义样式,并从 actionModePopupWindowStyle 指向它。

您提出的解决方案对于工具栏及其溢出菜单效果良好,但对于CAB中的溢出菜单则无效。我已经尝试过了,上下文操作栏的菜单仍未被样式化... - Sandra
请查看更新后的答案。操作模式需要“老派”的样式。 - Eugen Pechanec
感谢您迄今为止的帮助,但我仍然无法使其正常工作。我在我的活动主题中实现了actionModePopupWindowStyle,并将其指向我的自定义样式,看起来像这样:<style name="My" parent="Widget.AppCompat.PopupWindow"><item name="android:popupBackground">@color/light_theme_background</item></style>。这仍然不能为上下文溢出菜单提供样式:( - Sandra
尝试将 actionModePopupWindowStyle 放置到 Toolbar 而不是 Activity 中。 - Eugen Pechanec

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