Android ActionBar菜单图标不显示问题求助
解决ActionBar子菜单不显示图标的问题
嘿,我来帮你搞定这个问题!你现在遇到的情况其实是Android系统的默认行为——标准的嵌套子菜单(SubMenu)是不会展示图标的,哪怕你在xml里明确设置了android:icon属性,系统也会自动忽略它。下面给你两种可行的解决方案,按需选择:
方案一:用PopupMenu实现带图标的下拉菜单
这是最快捷的方式,只需要调整菜单结构和添加少量代码:
1. 修改主菜单xml(top_menu.xml)
把嵌套的子项拆出来,只保留触发下拉的主按钮:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_more" android:icon="@drawable/ic_ihbpro" android:title="one" app:showAsAction="always"/> </menu>
2. 创建子菜单xml(sub_menu.xml)
把原来的子项单独放在这个文件里:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/Home" android:title="Home" android:icon="@drawable/ic_dashboard"/> <item android:id="@+id/ihbprom" android:title="IHB" android:icon="@drawable/ic_ihbpro"/> <item android:id="@+id/Account" android:title="Account" android:icon="@drawable/ic_account"/> </menu>
3. 修改Java代码,添加PopupMenu逻辑
在Activity里重写onOptionsItemSelected,给主菜单按钮绑定弹出逻辑,并且强制PopupMenu显示图标:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.top_menu, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_more) { // 创建PopupMenu,绑定到主菜单按钮的位置 PopupMenu popupMenu = new PopupMenu(this, findViewById(R.id.action_more)); // 加载子菜单 popupMenu.getMenuInflater().inflate(R.menu.sub_menu, popupMenu.getMenu()); // 关键:通过反射强制PopupMenu显示图标(系统默认不显示) try { Field field = popupMenu.getClass().getDeclaredField("mPopup"); field.setAccessible(true); MenuPopupHelper helper = (MenuPopupHelper) field.get(popupMenu); helper.setForceShowIcon(true); } catch (Exception e) { e.printStackTrace(); } // 处理子菜单的点击事件 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.Home: // 这里写Home项的点击逻辑 return true; case R.id.ihbprom: // 这里写IHB项的点击逻辑 return true; case R.id.Account: // 这里写Account项的点击逻辑 return true; default: return false; } } }); popupMenu.show(); return true; } return super.onOptionsItemSelected(item); }
方案二:自定义PopupWindow实现完全可控的菜单
如果需要更个性化的样式(比如调整图标大小、文字颜色、菜单背景等),可以用自定义布局的PopupWindow:
1. 创建自定义菜单项布局(item_menu_custom.xml)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="12dp" android:orientation="horizontal" android:gravity="center_vertical" android:clickable="true" android:focusable="true"> <ImageView android:id="@+id/menu_icon" android:layout_width="24dp" android:layout_height="24dp" android:marginEnd="12dp"/> <TextView android:id="@+id/menu_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp"/> </LinearLayout>
2. 创建菜单数据类(可选)
用来存储每个菜单项的图标和标题:
public class MenuItemData { private int iconRes; private String title; private int itemId; public MenuItemData(int itemId, int iconRes, String title) { this.itemId = itemId; this.iconRes = iconRes; this.title = title; } // getter方法 public int getIconRes() { return iconRes; } public String getTitle() { return title; } public int getItemId() { return itemId; } }
3. 在Activity中实现PopupWindow逻辑
@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_more) { // 准备菜单数据 List<MenuItemData> menuData = new ArrayList<>(); menuData.add(new MenuItemData(R.id.Home, R.drawable.ic_dashboard, "Home")); menuData.add(new MenuItemData(R.id.ihbprom, R.drawable.ic_ihbpro, "IHB")); menuData.add(new MenuItemData(R.id.Account, R.drawable.ic_account, "Account")); // 创建PopupWindow View popupView = getLayoutInflater().inflate(R.layout.popup_menu_custom, null); ListView menuListView = popupView.findViewById(R.id.menu_list); // 设置适配器 MenuAdapter adapter = new MenuAdapter(this, menuData); menuListView.setAdapter(adapter); PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); popupWindow.setOutsideTouchable(true); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE)); // 设置点击事件 menuListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MenuItemData data = menuData.get(position); switch (data.getItemId()) { case R.id.Home: // 处理Home点击 break; case R.id.ihbprom: // 处理IHB点击 break; case R.id.Account: // 处理Account点击 break; } popupWindow.dismiss(); } }); // 显示PopupWindow,位置在主菜单按钮下方 popupWindow.showAsDropDown(findViewById(R.id.action_more)); return true; } return super.onOptionsItemSelected(item); } // 自定义适配器 private class MenuAdapter extends ArrayAdapter<MenuItemData> { public MenuAdapter(Context context, List<MenuItemData> data) { super(context, 0, data); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.item_menu_custom, parent, false); } MenuItemData data = getItem(position); ImageView icon = convertView.findViewById(R.id.menu_icon); TextView title = convertView.findViewById(R.id.menu_title); icon.setImageResource(data.getIconRes()); title.setText(data.getTitle()); return convertView; } }
(注:需要创建对应的popup_menu_custom.xml,里面放一个ListView即可)
为什么原来的方式不行?
Android的SubMenu(就是你原来xml里嵌套的子菜单)是系统UI组件的一部分,按照设计规范,它默认就是不展示图标的,所以无论你怎么设置android:icon属性,系统都会忽略这个配置,这就是你看不到图标的原因。
内容的提问来源于stack exchange,提问作者Koushik Deb
相关产品推荐
相关产品推荐

