Android在menuItem中添加子菜单,addSubMenu()在哪里?

ruh*_*lde 40 android menu menuitem submenu

我想根据我的参数以编程方式将我的OptionsMenu中的子菜单添加到menuItem.我在android sdk中检查了"MenuItem"并且没有addSubMenu()方法!,尽管你可以找到"hasSubMenu()"和"getSubMenu".

正在考虑在onCreateOptionsMenu中这样做:

public boolean onCreateOptionsMenu(Menu menu) {

    MenuItem mi = menu.getItem(MYITEMID);  // << this is defined in my XML optionsMenu
    SubMenu subm = mi.addSubMenu(0,1,0,"Map 1"); // no addSubMenu() method!!!???
....
Run Code Online (Sandbox Code Playgroud)

如何在代码中的menuitem中创建子菜单?

ruh*_*lde 67

有时Android怪异真的很棒(而且有趣......).我这样解决了:

a)在XML中定义一个子菜单占位符,如下所示:

<item android:visible="true" android:id="@+id/m_area"
   android:titleCondensed="Areas"
   android:title="Areas"
   android:icon="@drawable/restaur"
   android:enabled="true"> 
   <menu>
    <item android:id="@+id/item1" android:title="Placeholder"></item>
   </menu>
</item>
Run Code Online (Sandbox Code Playgroud)

b)在OnCreateOptionsMenu中获取子菜单项,清除它并添加我的子菜单项,如下所示:

    public boolean onCreateOptionsMenu(Menu menu) { 
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.mapoptions, menu);

            int idx=0;
            subm = menu.getItem(MYITEM_INDEX).getSubMenu(); // get my MenuItem with placeholder submenu
            subm.clear(); // delete place holder

            while(true)
            {
                anarea = m_areas.GetArea(idx); // get a new area, return null if no more areas
                if(anarea == null)
                    break;
                subm.add(0, SUBAREASID+idx, idx, anarea.GetName()); // id is idx+ my constant
                ++idx;
            }
}
Run Code Online (Sandbox Code Playgroud)

  • 我们可以务实地打开这个菜单下拉菜单吗? (2认同)
  • 对不起,但是我真的发现变量名让我感到困惑。什么是anarea?那是什么类型 m_areas的类型是什么,所以我可以查找GetArea()方法。如果您可以向我们显示这些变量的声明,这将有所帮助:) (2认同)

Ein*_* H. 25

我知道这是一个老问题,但我自己也遇到过这个问题.这样做最直接的方法似乎是简单地将项目本身指定为子菜单,然后添加到此项目.例如:

menu.add(groupId, MENU_VIEW, Menu.NONE, getText(R.string.menu_view));
menu.add(groupId, MENU_EDIT, Menu.NONE, getText(R.string.menu_edit));
SubMenu sub=menu.addSubMenu(groupId, MENU_SORT, Menu.NONE, getText(R.string.menu_sort));
sub.add(groupId, MENU_SORT_BY_NAME, Menu.NONE, getText(R.string.menu_sort_by_name));
sub.add(groupId, MENU_SORT_BY_ADDRESS, Menu.NONE, getText(R.string.menu_sort_by_address));
:
:
Run Code Online (Sandbox Code Playgroud)

  • @MarkLapasa,你可以做`sub.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);`来修复它. (5认同)
  • 我发现,一旦以编程方式添加子菜单,它将始终将父菜单添加到溢出菜单中,显式忽略任何标志以始终在操作栏上显示它.这是有问题的,因为要进入子菜单,它会添加额外的打开溢出菜单.您可以通过跳过上面代码的第一行来尝试我正在谈论的内容. (3认同)

Rob*_*ert 19

这是一个完整的答案,它基于使用占位符的想法,但主要使用xml来添加子菜单.

如果你有一个像所谓的main_menu.xml这样的菜单:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="My Menu"
    android:id="@+id/my_menu_item">
    <!-- A empty SubMenu -->
    <menu></menu>
</item>
</menu>
Run Code Online (Sandbox Code Playgroud)

创建另一个将在my_menu_item中使用的菜单sub_menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:title="SubMenu One"
    android:id="@+id/submenu_one" />
  <item android:title="SubMenu Two"
    android:id="@+id/submenu_two" />
  <item android:title="SubMenu Three"
    android:id="@+id/submenu_three" />
</menu>
Run Code Online (Sandbox Code Playgroud)

在你的onCreateOptionsMenu中:

public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate your main_menu into the menu
   getMenuInflater().inflate(R.menu.main_menu, menu);

   // Find the menuItem to add your SubMenu
   MenuItem myMenuItem = menu.findItem(R.id.my_menu_item);

   // Inflating the sub_menu menu this way, will add its menu items 
   // to the empty SubMenu you created in the xml
   getMenuInflater().inflate(R.menu.sub_menu, myMenuItem.getSubMenu());

}
Run Code Online (Sandbox Code Playgroud)

这个解决方案很好,因为inflater处理大部分工作.


Phi*_*hil 17

执行此操作的最佳方法是在xml菜单文件中.您可以通过在以下内容中创建新menu对象来执行此操作item:

<menu>
  <item>
    ...
    <menu>
      ...
    </menu>
    ...
  </item>
</menu>
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我通过在我的MenuItem中放置一个占位符子菜单,使用getItem().getSubMenu()以编程方式获取该子菜单,清除它并使用add()添加我的子菜单项来解决.我会在以后系统发布代码时让我这么做,我只能在我的问题发布8小时之后才能做到这一点,顺便说一句,这真的是一个蹩脚的功能,如果我自己的回复没有增加我的声誉而不是能够发布我的答案,它真的很荒谬.. (2认同)