Android 在工具栏溢出菜单中显示菜单项图标时,这种奇怪的情况是如何发生的?

Android 在工具栏溢出菜单中显示菜单项图标时,这种奇怪的情况是如何发生的?,android,menu,toolbar,android-appcompat,Android,Menu,Toolbar,Android Appcompat,我想在工具栏(AppCompat-v7:22.1.1)中显示一个溢出菜单,下面是我的菜单\u 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&quo

我想在工具栏(AppCompat-v7:22.1.1)中显示一个溢出菜单,下面是我的菜单\u 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" />
但是在运行这个演示之后,我发现图标仍然没有显示出来

由此,我知道在22.x中不再调用
AppCompatiActivity.onMenuOpen
,但奇怪的是,当我在Genymotion中单击硬件菜单键时,菜单显示在底部,并带有图标

关闭菜单后,我再次单击工具栏上的溢出按钮,菜单中的这些图标出现

真奇怪!为什么会发生这种情况?

对于,您可以将此检查放在on prepareoptionspanel()上


这是对阿尔西奥·卡瓦略(Alécio Carvalho)上述优秀答案的修改。如果需要正确显示图标,而不是在主应用程序的操作栏中,而是在每个单独片段内的自定义工具栏中,则需要进行此修改(我想要一个单独的工具栏,每个片段都有自己的标题和自定义的操作菜单,而不是简单地向整个活动的操作栏添加新项目)

对于上述情况,片段类如下所示:

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>
我是这样解决的

这对我来说很有用

  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.my_menu, menu);

        //this section is the one that allows to visualize the icon
        if(menu instanceof MenuBuilder){
            MenuBuilder m = (MenuBuilder) menu;
            //noinspection RestrictedApi
            m.setOptionalIconsVisible(true);
        }

        return true;
    }

这可能是一个品味的问题,但我认为
if(menu.getClass().equals(MenuBuilder.class))
if(menu.getClass().getSimpleName().equals(“MenuBuilder”)
更优雅。硬编码的字符串越少,IMHO;-)忽略我的评论。按自己的方式操作,可以让Android的原生MenuBuilder和AppCompat都能使用。干得好!如果您使用这个和proguard,您需要排除适当的类:
-保留类android.support.v7.view.menu.MenuBuilder{*;}-保留类com.android.view.menu.MenuBuilder{*;}
对于不扩展appcompatactivity的片段和活动,您如何处理黑白交替的颜色?使用always/never代替ifRoom来强制哪些人去哪里?太棒了!这个答案还说明了如何在
片段
中部署
工具栏
的更一般问题,该片段具有
设置选项菜单(false)。IE:如何使
活动
片段
菜单系统完全离散。
<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>
<fragment android:id="@+id/my_fragment_id"
android:name="com.appspot.trendy.trendychart.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
@SuppressLint("RestrictedApi")
public void initToolBar(){    
    MenuBuilder menuBuilder = (MenuBuilder) toolbar.getMenu();
    menuBuilder.setOptionalIconsVisible(true);
}
  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.my_menu, menu);

        //this section is the one that allows to visualize the icon
        if(menu instanceof MenuBuilder){
            MenuBuilder m = (MenuBuilder) menu;
            //noinspection RestrictedApi
            m.setOptionalIconsVisible(true);
        }

        return true;
    }