Search code examples
androidmenuautomationselectioncheckmark

Group menu items work but don't display checkmark


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

}

Solution

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