Подтвердить что ты не робот

Пункт меню Android Checkable

У меня есть следующее меню в приложении для Android:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/item1" 
          android:titleCondensed="Options"
          android:title="Highlight Options" 
          android:icon="@android:drawable/ic_menu_preferences" />

   <item android:id="@+id/item2" 
         android:titleCondensed="Persist"
         android:title="Persist" 
         android:icon="@android:drawable/ic_menu_preferences" 
         android:checkable="true" />
</menu>

Моя проблема в том, что второй пункт меню не отображается как "проверяемый" при запуске моего приложения в эмуляторе Android. Должен быть зеленый тик о предмете, не так ли? Чтобы указать, что его можно проверить.

Я что-то делаю неправильно?

4b9b3361

Ответ 1

Макет выглядит правильно. Но вы должны проверить и снять отметку с пункта меню в коде.

В документации :

Когда выбирается проверяемый элемент, система вызывает ваш выбранный вами метод обратного вызова (например, onOptionsItemSelected()). Именно здесь вы должны установить состояние флажка, потому что флажок или переключатель не меняют свое состояние автоматически. Вы можете запросить текущее состояние элемента (как это было до того, как пользователь его выбрал) с помощью isChecked(), а затем установить установленное состояние с помощью setChecked().

Ответ 2

Оберните item в элементе group, например:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="all">
        <item android:id="@+id/item1"
              android:titleCondensed="Options"
              android:title="Highlight Options"
              android:icon="@android:drawable/ic_menu_preferences">
        </item>
        <item android:id="@+id/item2"
              android:titleCondensed="Persist"
              android:title="Persist"
              android:icon="@android:drawable/ic_menu_preferences"
              android:checkable="true">
        </item>
    </group>
</menu>

Из Android docs:

Атрибут android: checkableBehavior принимает либо:

single - Можно проверить только один элемент из группы (переключатели)

all - все элементы могут быть отмечены (флажки)

none - Нет элементов, которые можно проверить

Ответ 3

Вы можете создать проверяемый элемент меню, установив actionViewClass на видимый виджетов, например android.widget.CheckBox

Рез/меню/ menu_with_checkable_menu_item.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorite"
        android:checkable="true"
        android:title="@string/action_favorite"
        app:actionViewClass="android.widget.CheckBox"
        app:showAsAction="ifRoom|withText" />
</menu>

И вы можете даже стилизовать его как проверяемую звезду, если вы установите actionLayout в макет с стилизованным android.widget.CheckBox

RES/макета /action_layout_styled_checkbox.xml

<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    style="?android:attr/starStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Рез/меню/ menu_with_checkable_star_menu_item.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorites"
        android:checkable="true"
        android:title="@string/action_favorites"
        app:actionLayout="@layout/action_layout_styled_checkbox"
        app:showAsAction="ifRoom|withText" />
</menu>

Чтобы установить значение

menuItem.setChecked(true/false);

Чтобы получить значение

menuItem.isChecked()

Вставить MenuItem в CheckBox

CheckBox checkBox= (CheckBox) menuItem.getActionView();

Ответ 4

Отвечаю, потому что ответы здесь кажутся длинными и запутанными. У меня есть точный код Котлина здесь

Переопределите свою активность сверху и переопределите функцию onMenuItemClick. Имейте функцию для обработки нажатия кнопки, чтобы открыть меню.

Иметь массив или список, который содержит проверенное значение и устанавливает проверку при повторном создании меню

Примечание. Этот код не оставляет меню открытым, он только гарантирует, что отмеченные пункты остаются отмеченными. Я отметил, что есть много решений для этого при переполнении стека, поэтому посмотрите на них, если это то, что вы хотите

class exampleActivity : AppCompatActivity(), PopupMenu.OnMenuItemClickListener {
   private var checkChecked = arrayListOf(false,false)
   //some code

  fun clickBTN(v: View){
        val popup = PopupMenu(this,v)
        popup.setOnMenuItemClickListener(this)
        popup.inflate(R.menu.yourmenufilename)
        //assuming you have 2 or more menu items
        popup.menu[0].isChecked = checkChecked[0]
        popup.menu[1].isChecked = checkChecked[1]
        popup.show()
  }

  override fun onMenuItemClick(item: MenuItem?): Boolean {
     when(item?.itemID){
        R.id.item0 -> {
                item.isChecked = !item.isChecked
                checkChecked[0] = item.isChecked
                return true
        }
        R.id.item1 -> {
                item.isChecked = !item.isChecked
                checkChecked[1] = item.isChecked
                return true
        }
  }
}

конечно, в XML у вас должны быть настройки кнопок и меню. Пример меню здесь

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/item0"
        android:title="@string/hi"
        android:checkable="true"/>
    <item android:id="@+id/item1"
        android:title="@string/yo"
        android:checkable="true"/>
</menu>

Ответ 5

Это может быть зависит от темы, но в моем меню не отображается флажок. Я нашел this:

Примечание. Элементы меню в меню значков не могут отображать флажок или радио кнопка. Если вы решите сделать элементы в меню значков, вы должны лично указать состояние, заменив значок и/или текст каждый раз, когда состояние изменяется между включением и выключением.

Ответ 6

Для добавления пунктов меню программно,

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    menu.add("Item1").setActionView(R.layout.action_layout_checkbox).setCheckable(true);
    return super.onCreateOptionsMenu(menu);
}

res/layout/action_layout_checkbox.xml

<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Ответ 7

ПРОЧИТАЙТЕ ЭТО

Как уже было сказано, "ручная проверка" - это только верхушка айсберга. Он так быстро отбрасывает меню, что пользователи не видят, что что-то происходит, и это очень противоречит интуитивному, разочаровывающему и фактически полному дерьму. REAL TASK (поэтому) разрешает переваривать события флажка пользователем.

Хорошие новости: это можно сделать, и оно работает, и вот как вы это делаете. У @TouchBoarder было лучше, поэтому я скопирую его код. затем развивайте его.

идея состоит в том, чтобы определить, был ли установлен флажок, а затем (и только в том случае, если этот флажок установлен) слегка подавить удаление меню, добавить таймер на 500 мс, затем закрыть меню, это даст анимацию "галочки" времени запуска флажка и создает правильное "чувство"

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorite"
        android:checkable="true"
        android:title="@string/action_favorite"
        app:actionViewClass="android.widget.CheckBox"
        app:showAsAction="ifRoom|withText" />
</menu>

затем вы делаете этот метод как обычно, но вы обязательно добавляете все эти дополнительные неровности

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the bottom bar and the top bar (weird)
    BottomAppBar bottomBar = findViewById(R.id.bottom_app_bar_help);
    Menu bottomMenu = bottomBar.getMenu();
    getMenuInflater().inflate(R.menu.bottom_nav_menu, bottomMenu);
    for (int i = 0; i < bottomMenu.size(); i++) {
        bottomMenu.getItem(i).setOnMenuItemClickListener(item -> {
            if (item.getItemId()==R.id.action_favorite){
                item.setChecked(!item.isChecked());
                // Keep the popup menu open
                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
                item.setActionView(new View(frmMain.this));
                item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                    @Override
                    public boolean onMenuItemActionExpand(MenuItem item) {
                        final Handler handler = new Handler();
                        handler.postDelayed(() -> bottomMenu.close(), 500);
                        return false;
                    }

                    @Override
                    public boolean onMenuItemActionCollapse(MenuItem item) {
                        final Handler handler = new Handler();
                        handler.postDelayed(() -> bottomMenu.close(), 500);
                        return false;
                    }
                });
                return false;
            }
            else {
                return onOptionsItemSelected(item);
            }
        });
    }
    return true;
}

другие события меню здесь

public boolean onOptionsItemSelected(MenuItem item) {
    // Bottom Bar item click
    try {
        switch (item.getItemId()) {
            case R.id.mnuExit:
                MenuClick(ClickType.LOGOUT);
                return true;

            case R.id.mnuList:
                MenuClick(ClickType.LIST);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return super.onOptionsItemSelected(item);
}