ActionBarSherlock: 如何使用菜单按钮打开子菜单

7
我正在使用ActionBarSherlock-4.1.0-0,我想用硬件菜单按钮在Actionbar中打开我的子菜单。我计划升级,在旧版中我使用了“普通”菜单。我想帮助用户适应新的设计。
我已经得到了子菜单和主菜单:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater i = getSupportMenuInflater();
    i.inflate(R.menu.main_menu, menu);
    SubMenu subMenu = (SubMenu) menu.findItem(R.id.actionbar_submenu);
    Menu mainMenu = menu;
    return super.onCreateOptionsMenu(menu);
}

我已获得一个监听硬件菜单按钮的功能:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(event.getAction() == KeyEvent.ACTION_DOWN){
        switch(keyCode) {
        case KeyEvent.KEYCODE_MENU:
            // TODO: expand submenu from actionbar
            return true;

        }
    }
    return super.onKeyDown(keyCode, event);
}

我找不到任何方法或其他可调用的东西。
3个回答

11

我尝试了Frederik的解决方案,使用android actionbar时遇到子菜单立即打开和关闭的问题。修改为onKeyUp解决了这个问题。

这是我的代码:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_MENU){
        if (event.getAction() == KeyEvent.ACTION_DOWN && optionsMenu != null && optionsMenu.findItem(R.id.sub_menu) != null)
        {
            Log.i(TAG, "performIdentifierAction");
            optionsMenu.performIdentifierAction(R.id.sub_menu, 0);
            return true;
        }
    }
    return super.onKeyUp(keyCode, event);
}

由于与没有操作栏的旧版Android版本存在兼容性问题,我会检查optionsMenu!=null&&optionsMenu.findItem(R.id.sub_menu)!=null。如果您为所有版本使用ActionBarSherlock,则不需要进行此操作。


4
应该是ACTION_UP,而不是ACTION_DOWN。 - kolobok

4
这是我解决问题的方法。
mainMenu.performIdentifierAction(id_of_menu_item, 0);

所以在你的情况下,我想应该是这样的。
private Menu mainMenu; // local variable for menu

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater i = getSupportMenuInflater();
    i.inflate(R.menu.main_menu, menu);
    SubMenu subMenu = (SubMenu) menu.findItem(R.id.actionbar_submenu);
    mainMenu = menu; // store the menu in an local variable
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(event.getAction() == KeyEvent.ACTION_DOWN){
        switch(keyCode) {
        case KeyEvent.KEYCODE_MENU:
            SubMenu subMenu = (SubMenu) mainMenu.findItem(R.id.actionbar_submenu);
            mainMenu.performIdentifierAction(subMenu.getItem().getItemId(), 0);

            return true;  
        }
    }
    return super.onKeyDown(keyCode, event);
}

简而言之:

  • 将菜单存储在本地变量中
  • 使用该变量查找子菜单
  • 使用该变量调用performIdentifierAction方法

希望这样可以解决问题。


感谢您的支持,但是当我实现您的解决方案时,我在mainMenu.performIdentifierAction(subMenu.getItem().getItemId(), 0)这一行遇到了java.lang.NullPointerException异常。subMenu对象为空,有什么建议吗? - Paul Spiesberger
这个想法是你需要找到子菜单的项目ID并使用它。你的子菜单ID是什么?(r.id.[theid])?在我的实现中,我会将MenuItem存储在本地变量中,并使用它来执行:getItemId()。 - Fredrik Sundmyhr

4

我之前使用Fredrik Sundmyhr的解决方案时总是遇到NullPointerException错误,后来我进行了一些修改并使其正常工作。以下是我的解决方案:

@Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if(event.getAction() == KeyEvent.ACTION_UP){
            switch(keyCode)
            {
            case KeyEvent.KEYCODE_MENU:
                SubMenu subMenu = mainMenu.getItem(2).getSubMenu();
                mainMenu.performIdentifierAction(subMenu.getItem().getItemId(), 0);

                return true;  
            }
        }
        return super.onKeyUp(keyCode, event);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接