Как это странное состояние происходит при отображении значка меню в меню переполнения панели инструментов?

Я хочу показать меню переполнения на панели инструментов (AppCompat-v7: 22.1.1), ниже – мое menu_main.xml.

<menu 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" tools:context=".MainActivity"> <item android:id="@+id/action_search" android:title="@string/action_search" android:icon="@mipmap/ic_menu_search" android:orderInCategory="100" android:actionViewClass="android.widget.SearchView" app:showAsAction="ifRoom"/> <item android:id="@+id/menu_group_chat" android:title="@string/menu_group_chat" android:icon="@mipmap/ic_menu_groupchat" /> <item android:id="@+id/menu_add_friend" android:title="@string/menu_add_friend" android:icon="@mipmap/ic_menu_add_friend" /> 

После запуска моего приложения значок элемента меню не отображается, затем я попробовал это решение , добавил метод переопределения onMenuOpened () в моей Activity (продолжается от AppCompatActivity),

 @Override public boolean onMenuOpened(int featureId, Menu menu) { if(menu!=null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try { Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { e.printStackTrace(); } } } return super.onMenuOpened(featureId, menu); } 

Но после запуска этой демонстрации я обнаружил, что значок все еще не отображается.

1. Меню с кнопкой переполнения

Из этой сообщенной проблемы я знаю, что AppCompatActivity.onMenuOpened больше не вызывается в 22.x, но странно, что когда я нажимаю клавишу меню аппаратного обеспечения в Genymotion, меню появляется внизу и со значком,

2. Меню с нажатием клавиши меню

После закрытия меню я снова нажимаю кнопку переполнения на панели инструментов, появляются эти значки в меню,

3. Меню с кнопкой переполнения

Как это странно! Почему это происходит?

Solutions Collecting From Web of "Как это странное состояние происходит при отображении значка меню в меню переполнения панели инструментов?"

Для AppCompactActivity вы можете поставить эту проверку на onPrepareOptionsPanel ().

 @Override protected boolean onPrepareOptionsPanel(View view, Menu menu) { if (menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { Log.e(getClass().getSimpleName(), "onMenuOpened...unable to set icons for overflow menu", e); } } } return super.onPrepareOptionsPanel(view, menu); } 

Вот модификация превосходного ответа, высказанного выше Алесио Карвалью. Эта модификация предназначена для случая, если необходимо правильно отображать значки не в панели действий основного приложения, а в пользовательских панелях инструментов внутри каждого отдельного фрагмента (мне нужна отдельная панель инструментов с собственным заголовком и собственным настраиваемым меню действий для каждого фрагмента, а не просто Добавление новых элементов в панель действий общей AppCompatActivity).

Для указанного случая класс Фрагмента выглядит следующим образом:

 public class MyFragment extends android.support.v4.app.Fragment { ... public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //at first get the very toolbar fragmentToolbar = (Toolbar) view.findViewById(R.id.fragment_toolbar); fragmentToolbar.setTitle(R.string.title_string); fragmentToolbar.showOverflowMenu(); //now ready to get the menu's method, which is responsible for icons, and change its properties Menu menu=fragmentToolbar.getMenu(); Method menuMethod = null; try { menuMethod = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); menuMethod.setAccessible(true); menuMethod.invoke(menu, true); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } //now all the other stuff necessary for the toolbar operation fragmentToolbar.inflateMenu(R.menu.my_fragment_menu); fragmentToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem arg0) { if(arg0.getItemId() == R.id.menu_item_1){ ... } return false; } }); //and now the main stuff of onCreateView View view = inflater.inflate(R.layout.my_fragment_layout, container, false); return view; } } 

Затем my_fragment_layout.xml включил меню следующим образом

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:id="@+id/fragment_toolbar" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:elevation="4dp"> </android.support.v7.widget.Toolbar> //...other items </LinearLayout> 

Типичный файл меню был реализован как res/menu/my_fragment_menu.xml . Фрагмент был добавлен в макете mainActivity просто как

 <fragment android:id="@+id/my_fragment_id" android:name="com.appspot.trendy.trendychart.MyFragment" android:layout_width="match_parent" android:layout_height="match_parent"/>