1

I have a working app with an overflow menu. All the code in the menu works, but no checkmarks are being shown after I click on a single-clickable, grouped menu item.

Am I doing something fundamentally wrong? I thought that this displaying of the checkmark was automatic to Android and that the system would do this for me. Android knows it is in a group, it knows that only one can be selected, and it knows which one I selected! So..... Android should know how to display the checkmarks.

Code

XML

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Calculator">
    <group
        android:checkableBehavior="single"
        android:visible="true">
        <item
            android:id="@+id/ui_simple"
            android:orderInCategory="100"
            app:showAsAction="ifRoom|withText"
            android:title="Regular"
            android:checkable="true"/>
        <item
            android:id="@+id/ui_doge"
            android:orderInCategory="100"
            app:showAsAction="ifRoom|withText"
            android:title="Doge"
            android:checkable="true"/>
        <item
            android:id="@+id/ui_static"
            android:orderInCategory="100"
            app:showAsAction="ifRoom|withText"
            android:title="Static"
            android:checkable="true"/>
    </group>

    <item android:title="Display Mode"
        android:orderInCategory="101" >
        <menu>
            <group android:checkableBehavior="single" android:visible="true"   >
                <item
                    android:id="@+id/mode_sign"
                    android:orderInCategory="100"
                    app:showAsAction="collapseActionView"
                    android:title="Sign Form"
                    android:checkable="true"/>
                <item
                    android:id="@+id/mode_noun"
                    android:orderInCategory="100"
                    app:showAsAction="collapseActionView"
                    android:title="Noun Form"
                    android:checkable="true"/>
                <item
                    android:id="@+id/mode_verb"
                    android:orderInCategory="100"
                    app:showAsAction="collapseActionView"
                    android:title="Verb Form"
                    android:checkable="true"/>
            </group>

        </menu>
    </item>

</menu>

UI

Note: I have tried switching all the breaks to return true, but nothing happens.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    switch (item.getItemId()) {

        case R.id.ui_simple :
            startActivity(new Intent(this, Calculator.class));
            break;

        case R.id.ui_doge :
            startActivity(new Intent(this, CalculatorDoge.class));
            break;

        case R.id.ui_static :
            startActivity(new Intent(this, CalculatorStatic.class));
            break;

        case R.id.mode_sign : display = BinaryOperation.Display.SIGN; break;
        case R.id.mode_verb : display = BinaryOperation.Display.VERB; break;
        case R.id.mode_noun : display = BinaryOperation.Display.NOUN; break;

    }

    return super.onOptionsItemSelected(item);

}
Christopher Rucinski
  • 4,737
  • 2
  • 27
  • 58

2 Answers2

3

While @Elltz provides a valuable solution to a problem in the code, there are a total of 2 issues in the code.

Problem 1

Do not set a checkable XML attribute in both the Menu Group and the individual MenuItems.

since in the XML there is <group android:checkableBehavior="single" it shows that radio buttons are desired; therefore, no item within the group should have android:checkable="true"

    <group 
        android:checkableBehavior="single"      <!-- ONLY HERE -->
        android:visible="true"   >
        <item
            android:id="@+id/mode_sign"
            android:orderInCategory="100"
            app:showAsAction="collapseActionView"
            android:title="Sign Form" />
        <item
            android:id="@+id/mode_noun"
            android:orderInCategory="100"
            app:showAsAction="collapseActionView"
            android:title="Noun Form"/>
        <item
            android:id="@+id/mode_verb"
            android:orderInCategory="100"
            app:showAsAction="collapseActionView"
            android:title="Verb Form"/>
    </group>

Problem 2

Again, @Elltz provides a good solution; however, it is slightly more complex than what it needs to be.

For Single Selection Only

    switch (item.getItemId()) {

        case R.id.ui_simple : startActivity(new Intent(this, Calculator.class)); return true;
        case R.id.ui_doge : startActivity(new Intent(this, CalculatorDoge.class)); return true;
        case R.id.ui_static : startActivity(new Intent(this, CalculatorStatic.class)); return true;

        // Single Selection - Radio Buttons
        case R.id.mode_sign :
            item.setChecked(true);    // ONLY THIS....HERE
            display = BinaryOperation.Display.SIGN;
            return true;

        case R.id.mode_verb :
            item.setChecked(true);    // HERE
            display = BinaryOperation.Display.VERB;
            return true;

        case R.id.mode_noun :
            item.setChecked(true);    // AND HERE
            display = BinaryOperation.Display.NOUN;
            return true;

        default : return super.onOptionsItemSelected(item);
    }

For Single OR Multi Selection

    // Single OR Multi Select - Radio Buttons or CheckBoxes
    switch (item.getItemId()) {

        case R.id.ui_simple : startActivity(new Intent(this, Calculator.class)); return true;
        case R.id.ui_doge : startActivity(new Intent(this, CalculatorDoge.class)); return true;
        case R.id.ui_static : startActivity(new Intent(this, CalculatorStatic.class)); return true;

        case R.id.mode_sign :
            item.setChecked(!item.isChecked());    // LIKE THIS...HERE
            display = BinaryOperation.Display.SIGN;
            return true;

        case R.id.mode_verb :
            item.setChecked(!item.isChecked());    // HERE
            display = BinaryOperation.Display.VERB;
            return true;

        case R.id.mode_noun :
            item.setChecked(!item.isChecked());    // AND HERE
            display = BinaryOperation.Display.NOUN;
            return true;

        default : return super.onOptionsItemSelected(item);
    }
Community
  • 1
  • 1
Christopher Rucinski
  • 4,737
  • 2
  • 27
  • 58
1

No

Menu items in the Icon Menu (from the options menu) cannot display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, you must manually indicate the checked state by swapping the icon and/or text each time the state changes.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
    case R.id.ui_simple:            
        if (item.isChecked()){ 
              item.setChecked(false);
        }else{
            item.setChecked(true);
        }
      startActivity(new Intent(this, Calculator.class));
        break;
    case R.id.ui_doge:
        //same goes here and everyone
        break;
   ....
    }
}

Hope it helps

Elltz
  • 10,730
  • 4
  • 31
  • 59
  • Do you know why Android can't do it itself? Also, should I have `break` or `return true`? – Christopher Rucinski May 27 '15 at 02:16
  • oh i tot i replied this comment already, android does not handle it because radioButtons and Checkboxes do not automatically change state, hence they are not changed or handled unless maybe you attach a compoundbutton interface.. well also break stops/jumps/skip a loop and continue outside the loop so when you use break the last line in your method outside the switch statement will be called, if you use return everything is skipped.@ChristopherRucinski – Elltz May 27 '15 at 20:54