Android Studio抽屉菜单分组标题样式设置失效问题
[2023年10月5日编辑]
我有一个drawer menu,从屏幕左侧滑动即可唤起,菜单包含多个分组标题,每个标题下有3-5个可点击的子菜单项。我无法让主分组标题(如“Manage Songs”,ID为@+id/menu_item_manage_songs_header,子项为Add New Songs、Edit Songs等)突出显示,比如设置不同背景色、字体大小和颜色。
我希望让“Manage Songs”这个分组标题突出显示,但找不到对应的设置位置。以下是我的DrawerLayout代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/drawer_layout" tools:openDrawer="start"> ... <!-- Navigation Drawer --> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" app:menu="@menu/drawer_menu" /> </androidx.drawerlayout.widget.DrawerLayout>
我的drawer_menu.xml代码如下:
<menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Header: Manage Songs --> <item android:id="@+id/menu_item_manage_songs_header" android:title="Manage Songs" android:enabled="false" app:showAsAction="always" app:actionLayout="@layout/custom_header_layout" android:itemTextAppearance="@style/GroupHeaderStyle"> <menu> <group android:id="@+id/group_songs"> <item android:id="@+id/menu_item_add_new_song" android:title="Add New Song" android:onClick="onNavigationItemSelected" /> <item android:id="@+id/menu_item_edit_songs" android:title="Edit Songs" android:onClick="onNavigationItemSelected" /> <item android:id="@+id/menu_item_open_song" android:title="Open Song" android:onClick="onNavigationItemSelected" /> <item android:id="@+id/menu_item_search_songs" android:title="Search Songs" android:onClick="onNavigationItemSelected" /> </group> </menu> </item> ... </menu>
我已尝试以下两种方法但均无效:
- 在Java代码中设置背景色:
- 类中声明:
MenuItem GROUP_SONGS; - 在onCreate()中初始化:
GROUP_SONGS = (MenuItem) navigationView.getMenu().findItem(R.id.menu_item_manage_songs_header); - 可修改标题文本:
GROUP_SONGS.setTitle("Changed [1]");有效,但GROUP_SONGS.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);无效(已知setTextSize不属于MenuItem类)
- 类中声明:
- 在
themes.xml中设置样式:
<style name="GroupHeaderStyle"> <item name="android:background">@color/light_orange</item> <item name="android:textSize">22sp</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/white</item> </style>
并通过itemTextAppearance引用该样式,但未生效。恳请提供解决方案。
解决方案
方法一:用自定义actionLayout完全控制标题样式
你已经给菜单item设置了app:actionLayout="@layout/custom_header_layout",只需正确实现这个布局文件即可:
创建res/layout/custom_header_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/header_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:background="@color/light_orange" android:textSize="22sp" android:textStyle="bold" android:textColor="@android:color/white" android:text="Manage Songs"/>
如果需要动态修改标题文本,可在Java代码中获取这个TextView:
View headerView = navigationView.getMenu().findItem(R.id.menu_item_manage_songs_header).getActionView(); TextView headerText = headerView.findViewById(R.id.header_title); headerText.setText("新的标题内容");
方法二:官方推荐的分组标题配置方式
Material Design的NavigationView支持直接给group设置标题,无需用嵌套菜单的item作为标题,修改drawer_menu.xml:
<menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/group_songs" android:headerTitle="Manage Songs"> <item android:id="@+id/menu_item_add_new_song" android:title="Add New Song" android:onClick="onNavigationItemSelected" /> <item android:id="@+id/menu_item_edit_songs" android:title="Edit Songs" android:onClick="onNavigationItemSelected" /> <!-- 其他子项 --> </group> <!-- 其他分组 --> </menu>
然后在themes.xml中定义分组标题的全局样式:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <!-- 其他主题属性 --> <item name="android:listSeparatorTextViewStyle">@style/GroupHeaderStyle</item> </style> <style name="GroupHeaderStyle"> <item name="android:background">@color/light_orange</item> <item name="android:textSize">22sp</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/white</item> <item name="android:padding">16dp</item> </style>
这种方式无需额外自定义布局,直接通过主题统一控制所有分组标题样式。
方法三:遍历菜单动态设置样式
如果需要保留原有菜单结构,可在Java代码中遍历菜单,找到分组标题item后修改其样式:
Menu menu = navigationView.getMenu(); MenuItem groupHeader = menu.findItem(R.id.menu_item_manage_songs_header); View headerView = groupHeader.getActionView(); if (headerView != null) { headerView.setBackgroundColor(getResources().getColor(R.color.light_orange)); TextView titleView = headerView.findViewById(android.R.id.title); if (titleView != null) { titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); titleView.setTypeface(titleView.getTypeface(), Typeface.BOLD); titleView.setTextColor(Color.WHITE); } }
内容的提问来源于stack exchange,提问作者kiteandwindsurfer

