Android-панель действий проверяемый пункт меню не работает / отображается правильно? - PullRequest
14 голосов
/ 16 ноября 2011

, поэтому я пытаюсь заставить свой пункт меню, то есть показывать на панели действий, вести себя как проверяемая опция меню. Первая часть работает, это означает, что ее можно проверить, и когда я нажимаю ее и устанавливаю в коде setChecked (true), она работает. Но что не работает, так это визуальная часть. Нет изменений в том, как элемент меню выглядит на панели действий в отмеченных и непроверенных состояниях? Я пытался использовать invalidateOptionsMenu (), но это не делает работу, и не только, с этой строкой в ​​моем коде я не могу выйти из проверенного состояния?!? Что происходит, так это то, что недействительные шансы OptionsMenu () отменяют проверенное состояние, и я в конечном итоге «зацикливаюсь», или при каждом нажатии этого пункта меню я продолжаю переходить к непроверенной части кода, где он проверяется, а при недействительности - непроверенный Я думаю ...

Вот код из моего файла XML для меню:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/lenslist_menu_add"
        android:showAsAction="always"
        android:title="@string/add"/>
    <item android:id="@+id/lenslist_menu_delete"
        android:showAsAction="always"
        android:checkable="true"
        android:title="@string/delete"/>
</menu>

А вот код Java:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch (item.getItemId()) {
    case R.id.lenslist_menu_add:

        return true;
    case R.id.lenslist_menu_delete:
        if (item.isChecked() == true) {
            item.setChecked(false);
            deleteMode = false;
            lensAdapter.setDeleteMode(false);
        } else {
            item.setChecked(true);
            deleteMode = true;
            lensAdapter.setDeleteMode(true);
        }
        lensAdapter.notifyDataSetChanged();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Спасибо!

Ответы [ 3 ]

32 голосов
/ 13 декабря 2011

Проверяемые элементы отображаются только в подменю или контекстных меню.

Вы используете их в качестве пунктов главного меню, поэтому оно не будет работать.

ИСТОЧНИК: Загрузите API DEMOS и откройте файл ApiDemos / res / menu / checkable.xml, вы увидите его как комментарий к строке 13. Я не знаю, почему они не упоминать об этом в документации для разработчиков

ссылка с комментарием .: http://alvinalexander.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/res/menu/checkable.xml.shtml

8 голосов
/ 23 июля 2015

Или просто сделай сам

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

и в onOptionsItemSelected do:

 ....
 menu_checked=!menu_checked;
 invalidateOptionsMenu();
4 голосов
/ 17 июня 2015

Лучшее решение - установить actionLayout из <Item> на CheckBox. Это решение предоставляет встроенный флажок (с анимацией материала и т. Д.) Со шрифтом, который соответствует другим элементам, и работает как в качестве действия, так и в подменю.

  1. Создайте новый макет с именем 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. Установите <Item> так. Обратите внимание, что вам нужны Checkable и Checked в том случае, если они отображаются в подменю (в этом случае actionLayout игнорируется.
<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. В вашем коде при создании меню нам нужно: а) установить заголовок флажка в соответствии с заголовком пункта меню, б) восстановить проверенное состояние как проверяемого меню, так и нашего дополнительного флажка, и в) добавьте прослушиватель onClicked () для нашего дополнительного флажка. В этом коде я сохраняю состояние флажка в 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;
    }
...