OptionsMenu only open once on Android 4.1

686 views Asked by At

i'm using this code to open a optionsmenu as a popup:

@Override
public boolean onPrepareOptionsMenu(Menu menu){
    openMenu();
    return true;
}

private void openMenu(){
    View popUpView = getLayoutInflater().inflate(R.layout.menu, null);
    popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                        , LayoutParams.WRAP_CONTENT
                                        , true);
    popUpMenu.setBackgroundDrawable(new BitmapDrawable());
    popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
    popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
    makePopUpMenuButtons(popUpView);
}

The Problem is, that on Android 4.1 the menu only open once. I read something about invalidateOptionsMenu(), but i don't know where to implement this method. Also eclipse says "The method invalidateOptionsMenu() isn't defined on...".

Does anyone know what to do so that the optionsmenu will open every time when the menu button is clicked?

Edit:

I don't use the android menu object, because i want to have a custom design. That's the reason why i create a popop in onPrepareOptionsMenu. So i don't use onOptionsItemSelected. My problem is that onPrepareOptionMenu is only called on the first click and after that only irregular.

On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().

This paragraph says i have to call invalidateOptionsMenu when my API is 3.0 and higher. But in my project all works fine with APIs lower then 4.1. I tried to call invalidateOptionsMenu after showing my popup, but eclipse gives an error, because the method is undefined...

3

There are 3 answers

0
bluerob On BEST ANSWER

This code solved my problem:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_MENU) {
        openMenu();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

private void openMenu(){
    View popUpView = getLayoutInflater().inflate(R.layout.menu, null);
    popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                        , LayoutParams.WRAP_CONTENT
                                        , true);
    popUpMenu.setBackgroundDrawable(new BitmapDrawable());
    popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
    popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
    makePopUpMenuButtons(popUpView);
}

But i don't know if it's the best possible way

6
Gru On
    @Override
    public boolean onPrepareOptionsMenu(Menu menu){
        //You need to pass the menu to open menu method
        openMenu(menu);
        return true;
    }
    //
    private void openMenu(Menu menu){
        //that menu can not be null
        View popUpView = getLayoutInflater().inflate(R.layout.menu, menu);
        popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                            , LayoutParams.WRAP_CONTENT
                                            , true);
        popUpMenu.setBackgroundDrawable(new BitmapDrawable());
        popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
        popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
        makePopUpMenuButtons(popUpView);

}

Try option menu

Read this Changing menu items at runtime paragraph in above link for your second query

Edit:

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub

        menu.clear();

        menu.add(0, MENU_Unsubscribe, Menu.NONE, "Pop UP");

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        if (item.getItemId() == MENU_Unsubscribe) {
            View popUpView = getLayoutInflater().inflate(R.layout.activity_new,
                    null);

            btnOK=(Button)popUpView.findViewById(R.id.btnOK);



            popUpMenu = new PopupWindow(popUpView,
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false);
//          popUpMenu.setBackgroundDrawable
            popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
            popUpMenu.showAtLocation(popUpView, Gravity.CENTER, 0, 0);
            popUpMenu.setOutsideTouchable(true);

            btnOK.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    popUpMenu.dismiss();
                }
            });

        }

        return super.onOptionsItemSelected(item);
    }
2
Ritesh Gune On

Following will make things more clear:

1. onCreateOptionsMenu()

To specify the options menu for an activity,you override onCreateOptionsMenu(). In this method, you can inflate your menu resource (defined in XML) into the Menu provided in the callback. For Android 2.3.x and lower, the system calls onCreateOptionsMenu() to create the options menu when the user opens the menu for the first time. However for Android 3.0 and higher, the system calls onCreateOptionsMenu() when starting the activity, in order to show items to the action bar.

After the system calls onCreateOptionsMenu(), it retains an instance of the Menu you populate and will not call onCreateOptionsMenu() again unless the menu is invalidated for some reason. However, you should use onCreateOptionsMenu() only to create the initial menu state and not to make changes during the activity lifecycle.

2. onOptionsItemSelected()

When the you select an item from the options menu the system calls your activity's onOptionsItemSelected() method. This method passes the MenuItem selected.

3. onPrepareOptionsMenu()

If you want to modify the options menu based on events that occur during the activity lifecycle, you can do so in the onPrepareOptionsMenu() method. This method passes you the Menu object as it currently exists so you can modify it, such as add, remove, or disable items.

On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).

On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().

For invalidateOptionsMenu() Refer this

For onPrepareOptionsMenu() Refer this

Hence you can try as follows:

In order to deal with backward compatibility add following in your activity.

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.Menu1:
            refreshMenu();
            break;
        case R.id.Menu2:
            refreshMenu();
            break;     
        }
        return super.onOptionsItemSelected(item);
    }

   public void refreshMenu() {
      if (Build.VERSION.SDK_INT >= 11) {
          invalidateOptionsMenu();
      }
   }

You can also refer this