vipirtti
vipirtti

Reputation: 1078

Prevent options menu from closing on OptionItemSelected

I got an options menu with a bunch of checkboxes in it. I'd like to check a bunch of them on or off, but the menu closes automaticly every time I check just one. Can I prevent the menu from closing when an item has been selected? I'd also want to control when the closing happens and when it's prevented.

Activity.cs (excluding everything not related to options menu)

public class Activity: ReactiveActivity<ViewModel>, IAppCompatCallback
{

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        var inflater = MenuInflater;
        inflater.Inflate(Resource.Menu.actions, menu);
        return true;
    }

    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        if(item.ItemId == Resource.Id.action_settings) {
           StartActivity(typeof(SettingsActivity));
        }
        else {
           //Code changing the view based on selections
        }
        return base.OnOptionsItemSelected(item);
    }
}

actions.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:title="Choose options...">
  <menu>
    <group android:checkableBehavior="all">
      <item android:id="@+id/checkOption1"
            android:title="Option 1" 
            android:checked="true" />
      <item android:id="@+id/checkOption2"
            android:title="Option 2"
            android:checked="true" />
      <item android:id="@+id/checkOption3"
            android:title="Option 3"
            android:checked="true" />
      <item android:id="@+id/checkOption4"
            android:title="Option 4"
            android:checked="true" />
      <item android:id="@+id/checkOption5"
            android:title="Option 5"
            android:checked="true" />
      <item android:id="@+id/checkOption6"
            android:title="Option 6"
            android:checked="true" />
      <item android:id="@+id/checkOption7"
            android:title="Option 7"
            android:checked="true" />
    </group>
  </menu>
  </item>
  <item android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:showAsAction="never"/>
</menu>

Upvotes: 6

Views: 2632

Answers (2)

user5507535
user5507535

Reputation: 1800

My situation is the same, menu items with checkboxes.

I didn't find a way to prevent it from closing but as a hack I reopen the options menu as soon as it closes, there's a problem that I couldn't figure out how to fix though, while opening and closing the options menu there's an animation, and I couldn't find a way to disable it even looking around and finding possible answers, all failed.

In our app we created a Toolbar and set it up as an ActionBar, then on your code you override this method and call toolbar.showOverflowMenu() to reopen the menu:

/**
 * Handles the overflow menu closing event
 *
 * Due to a possible Android bug this is called twice!
 */
override fun onPanelClosed(featureId: Int, menu: Menu)
{
    if (something)    toolbar.showOverflowMenu()
}

You should use some rule to avoid having the menu opening itself non stop like the if statement on the example.

On the menu itself after the checkboxes I added an OK button, when the user clicks it I change a Boolean (something on the example) and avoid reopening the menu again.

Upvotes: 1

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

I got an options menu with a bunch of checkboxes in it. I'd like to check a bunch of them on or off, but the menu closes automaticly every time I check just one. Can I prevent the menu from closing when an item has been selected? I'd also want to control when the closing happens and when it's prevented.

For Menus, I didn't find a proper way to control the closing behavior.

But for your requirement, Dialog is a much better choice:

  1. remove the sub menu in your action.xml and add an id for Choose Options... Item:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:title="Choose options..." android:id="@+id/chooseOption"></item>
      <item android:id="@+id/action_settings"
            android:title="Settings"
            android:showAsAction="never"/>
    </menu>
    
  2. Create your DialogFragment together with AlertDialog:

    public class MyDialogFragment:DialogFragment
    {
        string[] Items { get; set; }
        bool[] CheckedItems { get; set; }
    
        public MyDialogFragment(string[] items,bool[] checkedItems)
        {
            Items = items;
            checkedItems = checkedItems;
        }
        public override Dialog OnCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this.Activity);
            builder.SetMultiChoiceItems(Items, CheckedItems, new DialogItemClickhandler());
            // Create the AlertDialog object and return it
            return builder.Create();
        } 
    }
    
    public class DialogItemClickhandler : Java.Lang.Object, IDialogInterfaceOnMultiChoiceClickListener
    {
        public void OnClick(IDialogInterface dialog, int which, bool isChecked)
        {
           //Item Click Implementation
        }
    }
    
  3. Open the dialog when user clicks the Choose Options... Menu Item:

    public class MainActivity : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView (Resource.Layout.Main);
        }
    
    
        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater.Inflate(Resource.Menu.Actions, menu);
            return true;
        }
    
        public override bool OnMenuItemSelected(int featureId, IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Resource.Id.chooseOption:
                    OpenDialogFragment();//Open the dialog
                    break;
                default:break;
            }
            return true;
        }
    
        private void OpenDialogFragment()
        {
    
            //init the Dialog items
            string[] items = new string[] {
                "Options 1",
                "Options 2",
                "Options 3",
                "Options 4",
                "Options 5",
                "Options 6"
            };
    
            bool[] checkedItems = new bool[] {
                true,
                false,
                true,
                false,
                true,
                false
            };
            MyDialogFragment dialog = new MyDialogFragment(items,checkedItems);
            dialog.Show(FragmentManager, "tag");
        }
    }
    

Upvotes: 2

Related Questions