Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionBarSherlock: open submenu with menu button

I'm using ActionBarSherlock-4.1.0-0 and I would like to open my submenu in the Actionbar with the hardware menu button. I'm planing an update and in my old version I used the "normal" menu. I'd like to help users to get used to the new design.

I got the submenu and the main-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);
    Menu mainMenu = menu;
    return super.onCreateOptionsMenu(menu);
}

and I got a listener to the hardware menu button:

@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);
}

I couldn't find a method or anything else to call.

like image 286
Paul Spiesberger Avatar asked Jul 10 '12 11:07

Paul Spiesberger


3 Answers

I try this solution from Frederik with android actionbar and I run into the problem that the submenu opens and closes immediately. Changing to onKeyUp solved this issue.

Here is my code:

@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);
}

I do check if optionsMenu != null && optionsMenu.findItem(R.id.sub_menu) != null because of compatibility issues with older Android versions without actionbar. This isn't nessesary if you use ActionBarSherlock for all versions.

like image 129
corban Avatar answered Nov 09 '22 22:11

corban


This is how I solved the issue

mainMenu.performIdentifierAction(id_of_menu_item, 0);

So in your case I would imagine it would be like this

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

In short:

  • Store the menu in a local variable
  • Use that variable to look for the sub menu
  • Use that variable to call the performIdentifierAction method

Hopefully this will work.

like image 38
Fredrik Sundmyhr Avatar answered Nov 09 '22 22:11

Fredrik Sundmyhr


I always got a NullPointerException with the solution of Fredrik Sundmyhr, then I changed a few things and it worked. Here's my solution:

@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);
    }
like image 31
Paul Spiesberger Avatar answered Nov 09 '22 22:11

Paul Spiesberger