Android action bar checkable menu item does not work/show properly?

后端 未结 3 2071
迷失自我
迷失自我 2020-12-06 10:05

so I am trying to get my menu item, that is show on the action bar to behave like a checkable menu option. The firs part works, meaning it is checkable and when I press it,

相关标签:
3条回答
  • 2020-12-06 10:42

    Checkable items appear only in submenus or context menus.

    You are using them as main menu items, hence it will not work.

    SOURCE: Download the API DEMOS, and open the file ApiDemos/res/menu/checkable.xml, you'll see it as a comment on line 13. I don't know why they don't mention this in the Developer Documentation

    reference with comment.: http://alvinalexander.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/res/menu/checkable.xml.shtml

    0 讨论(0)
  • 2020-12-06 11:04

    The best solution is to set the actionLayout of the <Item> to a CheckBox. This solution gives you a native-looking checkbox (with material animations etc), with a font that matches the other items, and it works both as an action and in the submenu.

    1. Create a new layout called action_checkbox.html:
    <?xml version="1.0" encoding="utf-8"?>
    <CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:paddingStart="8dp"
              android:paddingEnd="8dp"
              android:checked="false"
              android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu"
              android:id="@+id/action_item_checkbox"
        />
    
    1. Set your <Item> like this. Note that you need the Checkable and Checked still in case it is shown in a sub-menu (in which case the actionLayout is ignored.
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
        <item android:id="@+id/menu_action_logging"
              android:title="@string/action_logging"
              android:orderInCategory="100"
              android:showAsAction="always"
              android:checkable="true"
              android:checked="false"
              android:actionLayout="@layout/action_checkbox"
            />
    </menu>
    
    1. In your code, when the menu is created we need to a) set the title of the checkbox to match the menu item title, b) restore the checked state of both the menu checkable, and our extra checkbox, and c) add an onClicked() listener for our extra checkbox. In this code I am persisting the state of the checkbox in a RetainedFragment.
        // Set the check state of an actionbar item that has its actionLayout set to a layout
        // containing a checkbox with the ID action_item_checkbox.
        private void setActionBarCheckboxChecked(MenuItem it, boolean checked)
        {
            if (it == null)
                return;
    
            it.setChecked(checked);
    
            // Since it is shown as an action, and not in the sub-menu we have to manually set the icon too.
            CheckBox cb = (CheckBox)it.getActionView().findViewById(R.id.action_item_checkbox);
            if (cb != null)
                cb.setChecked(checked);
        }
    
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
        {
            inflater.inflate(R.menu.menu_main, menu);
            super.onCreateOptionsMenu(menu, inflater);
    
            // Restore the check state e.g. if the device has been rotated.
            final MenuItem logItem = menu.findItem(R.id.menu_action_logging);
            setActionBarCheckboxChecked(logItem, mRetainedFragment.getLoggingEnabled());
    
            CheckBox cb = (CheckBox)logItem.getActionView().findViewById(R.id.action_item_checkbox);
            if (cb != null)
            {
                // Set the text to match the item.
                cb.setText(logItem.getTitle());
                // Add the onClickListener because the CheckBox doesn't automatically trigger onOptionsItemSelected.
                cb.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onOptionsItemSelected(logItem);
                    }
                });
            }
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.menu_action_logging:
                    // Toggle the checkbox.
                    setActionBarCheckboxChecked(item, !item.isChecked());
    
                    // Do whatever you want to do when the checkbox is changed.
                    mRetainedFragment.setLoggingEnabled(item.isChecked());
                    return true;
                default:
                    break;
            }
    
            return false;
        }
    
    0 讨论(0)
  • 2020-12-06 11:07

    Or just do it yourself

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.findItem(R.id.item1).setIcon(menu_checked?R.drawable.menu_ico_checked:R.drawable.menu_ico_unchecked);
        return super.onPrepareOptionsMenu(menu);
    }
    

    and in onOptionsItemSelected do:

     ....
     menu_checked=!menu_checked;
     invalidateOptionsMenu();
    
    0 讨论(0)
提交回复
热议问题