Android给一个menuItem添加子菜单,addSubMenu()在哪里?

Posted

技术标签:

【中文标题】Android给一个menuItem添加子菜单,addSubMenu()在哪里?【英文标题】:Android adding a submenu to a menuItem, where is addSubMenu()? 【发布时间】:2011-10-25 22:58:14 【问题描述】:

我想根据我的参数以编程方式将 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!!!???
....

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

【问题讨论】:

我认为这个问题已经有了答案,在 *** 上。希望这有帮助!你应该检查这个:http://***.com/questions/6543745/create-sub-menu-in-android-through-code 对不起,但这不是我想要的。我已经用 XML 定义了一个选项菜单,我想通过代码以编程方式向该选项菜单的 MenuItem 添加一个子菜单。 【参考方案1】:

有时,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>

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

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

            int idx=0;
            SubMenu 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;
            

【讨论】:

我们可以务实地打开这个下拉菜单吗? 我很抱歉,但我真的发现变量名称让我感到困惑。什么是面积?那是什么类型的? m_areas 的类型是什么,所以我可以查找 GetArea() 方法。如果您能向我们展示这些变量的声明,将会有所帮助:)【参考方案2】:

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

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));
:
:

【讨论】:

+1:是的。好决定。不知道为什么我是第一个对此表示赞同的人。 我发现只要您以编程方式添加子菜单,它就会始终将父菜单添加到溢出菜单中,显式忽略任何标志以始终在操作栏上显示它。这是有问题的,因为要进入子菜单,它增加了打开溢出菜单的额外点击。您可以通过跳过上面代码的第一行来尝试我在说什么。 @MarkLapasa,你可以通过sub.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 来解决这个问题。 groupId 来自哪里?我试图在我的 xml 中创建一个组并设置一个 id,但我无法检索它。是一个随机的唯一 int 吗?【参考方案3】:

这是一个完整的答案,它基于使用占位符的想法,但主要使用 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>

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

<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>

在您的 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());


这个解决方案很好,因为充气机可以处理大部分工作。

【讨论】:

【参考方案4】:

最好的方法是在您的 xml 菜单文件中。您可以通过在 item 内创建一个新的 menu 对象来做到这一点:

<menu>
  <item>
    ...
    <menu>
      ...
    </menu>
    ...
  </item>
</menu>

【讨论】:

以编程方式?这是我的问题,我已经定义了一个 XML 选项菜单,我想通过代码向 MenuItem 添加一个子菜单。 对不起,但是是的 --> java.lang.ClassCastException,不能这样做 似乎没有办法以编程方式做到这一点。如果您检查“添加”方法及其重载对,每个人都有一个 Title 属性,表明将始终创建一个新的 ItemMenu。我猜我必须走其他路,也许不是在 XML 中定义我的 menuitem 并在 addSubmenu() 中以编程方式创建它。 好的,我通过在我的 MenuItem 中放置一个占位符子菜单解决了这个问题,使用 getItem().getSubMenu() 以编程方式获取该子菜单,清除它并使用 add() 添加我的子菜单项。当这个系统允许我稍后发布代码时,我只能在我的问题 8 小时后才发布代码,顺便说一句,这真的是一个蹩脚的功能,如果我自己的回复不会增加我的声誉而不是没有会更好能够发布我的答案,这真的很可笑.. @Phil:是的,我就是这样做的,但我无法更改子菜单样式。关于如何做到这一点的任何线索?【参考方案5】:

为了提供 Phil 答案的全面示例,这里是我完整的、可工作的 XML 用于具有两个选项的菜单,每个选项都是具有三个选项的菜单。我打算在顶层添加第三个菜单...

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:htmlCode="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/Examine"
        android:title="@string/Examine"
        HTMLCode:showAsAction="always">

        <menu xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
            <item android:id="@+id/load"
                android:title="@string/load"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item android:id="@+id/findfirst"
                android:title="@string/findfirst"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item android:id="@+id/findnext"
                android:title="@string/FindNext"
                HTMLCode:showAsAction="ifRoom|withText" />
        </menu>
    </item>

    <item android:id="@+id/Redirect"
        android:title="@string/Redirect"
        HTMLCode:showAsAction="ifRoom|withText">

        <menu xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
            <item android:id="@+id/getRedirect"
                android:title="@string/getRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item android:id="@+id/toggleRedirect"
                android:title="@string/toggleRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item android:id="@+id/copyRedirect"
                android:title="@string/copyRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />
        </menu>
    </item>
</menu>

【讨论】:

【参考方案6】:

您应该考虑改用 ActionProvider。

public class MyActionProvider extends ActionProvider 

    private Context mContext;

    public MyActionProvider(Context context) 
        super(context);

        mContext = context;
    

    @Override
    public View onCreateActionView() 
        //LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        return null;
    

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) 
        super.onPrepareSubMenu(subMenu);

        subMenu.clear();

        subMenu.add("menu 1");
        subMenu.add("menu 2");
        subMenu.add("menu 3");
    

    @Override
    public boolean hasSubMenu() 
        return true;
    

    @Override
    public boolean onPerformDefaultAction() 
        return super.onPerformDefaultAction();
    

【讨论】:

【参考方案7】:

我只会在 xml 文件中创建子菜单,并在运行时从菜单对象获取子菜单(使用 findItem(id) 方法)并使用 submenu.setVisible(boolean) 在运行时添加/删除它。

【讨论】:

【参考方案8】:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu1" android:alphabeticShortcut="a"
    android:title="Menu No. 1" android:orderInCategory="1" />
<item android:id="@+id/menu2" android:alphabeticShortcut="b"
    android:title="Menu No. 2" android:orderInCategory="2">
    <menu >
    <group android:id="@+id/group2" android:checkableBehavior="single">
        <item android:id="@+id/submenu1" android:title="SubMenu No. 1" />
        <item android:id="@+id/submenu2" android:title="SubMenu No. 2" />
    </group>   
    </menu>
</item>

【讨论】:

以上是关于Android给一个menuItem添加子菜单,addSubMenu()在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中创建带有子菜单的弹出菜单

VC/MFC怎样给菜单项添加勾啊

如何更改 Android 上选项菜单上的 MenuItem?

PrimeFaces MenuItem从右到左显示

将 MenuItem 添加到已经存在的 WPF 标题菜单

C#.NET中如何设置CONTEXTMENU菜单项的点击事件