android - 更改弹出菜单背景颜色

标签 android android-layout themes android-toolbar android-theme

NOTE: I have searched for an hour and tried all solutions already provided by stackoverflow.

我正在研究主题叠加。我制作了一个示例应用程序,它会在单击操作栏图标时打开一个弹出菜单。这是我的 styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>



    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Light">
        <item name="android:textColorPrimary">@color/colorAccent</item>
    </style>

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Dark">
        <!-- added all to see which one will work.-->
        <item name="android:popupMenuStyle">@style/PopupMenu</item>
        <item name="android:itemBackground">@color/colorAccent</item>
        <item name="android:colorBackground">@color/colorAccent</item>

    </style>

    <style name="PopupMenu" parent="@android:style/Widget.PopupMenu">
        <item name="android:popupBackground">@color/colorAccent</item>
    </style>

</resources>

这是我的工具栏样式。

   <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </android.support.design.widget.AppBarLayout>

我已将 popupTheme 设置为我在 styles.xml 中的那个。现在我想改变弹出菜单的背景颜色,目前是白色的。

enter image description here

这是代码。

 @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if(item.getItemId() == R.id.standard_menu){
            showPopupMenu(item);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void showPopupMenu(MenuItem item) {
        PopupMenu p = new PopupMenu(this, findViewById(item.getItemId()));
        p.inflate(R.menu.pop_menu);
        p.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(MainActivity.this, "clicked.", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
        p.show();
    }

最佳答案

我对接受的答案不满意,因为它并没有真正解释为什么没有应用 OPs 自定义弹出样式——不仅是背景,还有文本颜色之类的东西——所以我做了我的自己的实验。

重要的是要注意 Toolbar 创建的弹出窗口(当它有菜单项时)与使用 PopupMenu 自己显示的弹出窗口之间存在差异。这些由不同的主题属性控制。另外,请注意有两个 PopupMenu 类:android.widget.PopupMenu , 和 android.support.v7.widget.PopupMenu .

您需要为显式显示的 PopupMenu 设置样式的主题属性是 android:popupMenuStylepopupMenuStyle。您有几个选项可以正确应用您的自定义样式:

(1) 在 Activity (或应用)的主题中使用android:popupMenuStyle

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- if using android.widget.PopupMenu -->
    <item name="android:popupMenuStyle">@style/PopupMenu</item>
    <!-- if using android.support.v7.widget.PopupMenu -->
    <item name="popupMenuStyle">@style/PopupMenu</item>
</style/>

<style name="PopupMenu" parent="ThemeOverlay.AppCompat.Dark">
    <item name="android:popupBackground">@color/popupBackground</item>
</style>

PopupMenu popup = new PopupMenu(this, anchorView);

请注意,这不需要在您的布局文件中添加任何额外内容。

(2)使用 ContextThemeWrapper

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- nothing special -->
</style/>

<style name="CustomPopupTheme" parent="ThemeOverlay.AppCompat.Dark">
    <!-- if using android.widget.PopupMenu -->
    <item name="android:popupMenuStyle">@style/PopupMenu</item>
    <!-- if using android.support.v7.widget.PopupMenu -->
    <item name="popupMenuStyle">@style/PopupMenu</item>
</style>

<style name="PopupMenu" parent="ThemeOverlay.AppCompat.Dark">
    <item name="android:popupBackground">@color/popupBackground</item>
</style>

ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.CustomPopupTheme);
PopupMenu popup = new PopupMenu(ctw, anchorView);

请注意,在构造 ContextThemeWrapper 时,这不会直接使用 R.style.PopupMenu。这似乎有点迂回,但如果您想将弹出窗口主题与 Activity 或应用程序主题分开(例如,可能只有某些弹出窗口需要您的特殊主题),这很有用。

(3) 使用您的 AppBarLayout 的上下文

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- nothing special -->
</style/>

<style name="AppBarOverlay" parent="ThemeOverlay.AppCompat.Light">
    <!-- if using android.widget.PopupMenu -->
    <item name="android:popupMenuStyle">@style/PopupMenu</item>
    <!-- if using android.support.v7.widget.PopupMenu -->
    <item name="popupMenuStyle">@style/PopupMenu</item>
</style>

<style name="PopupMenu" parent="ThemeOverlay.AppCompat.Dark">
    <item name="android:popupBackground">@color/popupBackground</item>
</style>

<style name="PopupOverlay" parent="ThemeOverlay.AppCompat.Dark">
    <!-- changes the background of the Toolbar's popup -->
    <item name="android:colorBackground">@color/popupBackground</item>
</style>


<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/PopupOverlay"/>

</android.support.design.widget.AppBarLayout>


AppBarLayout appBar = (AppBarLayout) findViewById(R.id.app_bar);
PopupMenu popup = new PopupMenu(appBar.getContext(), anchorView);

因为您已经有了 AppBar 的主题覆盖,您可以使用它来保存您的弹出式主题引用。这也适用于工具栏的上下文,至少给定当前布局,但请注意 app:popupTheme 实际上在这里并不相关,因为它会影响 Toolbar 的弹出窗口和不是您的 PopupMenu。另请注意这与上面的选项 2 有何相似之处,这应该会让您了解 android:theme 属性在幕后是如何工作的;)

在我的实验中,android:itemBackground 仅在我用它代替 PopupOverlay 样式中的 android:colorBackground 时才起作用。但是,最好使用 android:colorBackground,因为这会改变弹出窗口的颜色,保留圆角和可选择的项目高亮/项目的波纹完好无损。

关于android - 更改弹出菜单背景颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40671629/

相关文章:

gtk - 从 XFCE 面板中移除阴影

java - 创建不同的 PendingIntent 对象 - 请求代码与不同的 Intent

android - 使用消息和使用 Twitter Auth 在 Twitter 上发布图像的简单技术是什么?

java - 从 Liferay 开始,对如何开始有点不知所措

java - 无法从布局文件夹引用布局

android - 将 ImageView 和 TextView 放在同一行

css - 我如何避免这个标题溢出?

android - 动态从字符串资源中获取字符串

android - 从 Android 图片库中选择图片 - PhoneGap 无法正常工作

Android 跨应用传递数据