Как предотвратить закрытие всплывающего меню при нажатии флажка

Я много ищу в сети, но ничего не мешает закрыть всплывающее меню.

Всякий раз, когда я нажимаю на элемент флажка или любой другой элемент всплывающего меню, всплывающее меню закрывается. Как я могу предотвратить его отклонение, когда пользователь устанавливает / снимает флажок во всплывающем меню.

Я показываю всплывающее меню в событии щелчка элемента меню панели действий.

//main_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.worldofjobs.woj.MainActivity" >

<item
    android:id="@+id/action_popUpMenu"
    android:icon="@drawable/ic_action_overflow"
    android:title="@string/main_action_popUpMenu"
    app:showAsAction="always"/>

</menu>

//popup_items.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item
    android:id="@+id/refresh_item"
    android:title="@string/main_refresh"/>
<item
    android:id="@+id/checkbox_item"
    android:checkable="true"
    android:title="Start notification"/>
<item
    android:id="@+id/changePasswrod_item"
    android:title="@string/main_changePassword"/>
<item
    android:id="@+id/deleteAccount_item"
    android:title="@string/main_deleteAccount"/>
<item
    android:id="@+id/logout_item"
    android:title="@string/main_logout"/>

</menu>

/**
 * Shows popup menu on click of action bar-menu inflates from
 * menu.pop_items-xml
 */
private void showPopup() {

    try {

        View v = findViewById(R.id.action_popUpMenu);

        PopupMenu popup = new PopupMenu(this, v);
        popup.setOnMenuItemClickListener(MainActivity.this);

        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.pop_items, popup.getMenu());
        popup.show();

    } catch (Exception e) {

        Log.e("MainActivity-showPopup:", e.toString());
    }
}

/**
 * Handles click events of popup menu items
 */
@Override
public boolean onMenuItemClick(MenuItem item) {

    super.onMenuItemSelected(1, item);
    switch (item.getItemId()) {

    case R.id.refresh_item:
        refresh();
        return true;

    case R.id.checkbox_item:
        return true;

    case R.id.changePasswrod_item:
        changePasswordPopup();
        return true;

    case R.id.deleteAccount_item:
        deleteAccount();
        return true;

    case R.id.logout_item:
        session.logout();
        finish();
        return true;
    }
    return true;
}

person Sushant    schedule 19.04.2015    source источник
comment
Где находится код флажка, пожалуйста, опубликуйте полный код.   -  person Ajit Kumar Dubey    schedule 19.04.2015
comment
Проверьте мой обновленный код (notification_item - checkbox_item). checkbox_item — пункт всплывающего меню, который можно отметить. Я еще ничего не делал с этим событием click/check, пока оно не перестанет закрывать всплывающее меню.   -  person Sushant    schedule 19.04.2015
comment
@sushant- Какой взгляд держится в v   -  person Ajit Kumar Dubey    schedule 19.04.2015
comment
main_menu.xml (элемент меню на панели действий)   -  person Sushant    schedule 19.04.2015
comment
@sushant- В этом случае вам нужно создать собственное представление, тогда вы сможете обрабатывать все, что хотите.   -  person Ajit Kumar Dubey    schedule 19.04.2015


Ответы (6)


Использование popupMenu.show() для немедленного повторного отображения всплывающего меню некорректно работает с пунктами меню, доступными для проверки, при изменении их отмеченных состояний.

Здесь метод, который предотвращает закрытие всплывающего меню в первую очередь. Убедитесь, что onMenuItemClick возвращает false.

popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem item) {

        item.setChecked(!item.isChecked());

        // Do other stuff

        // Keep the popup menu open
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
        item.setActionView(new View(context));
        item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                return false;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                return false;
            }
        });
        return false;
    }
});
person Oliver Jonas    schedule 30.07.2015
comment
Это дало мне сообщение об ошибке, в котором говорилось, что мне нужно использовать MenuItemCompat. У меня есть измененный код в моем ответе ниже (stackoverflow.com/a/44296077/2423194). - person Rock Lee; 01.06.2017

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

popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
    if(item.getItemId()==R.id.search_by_date_checkbox){
        item.setChecked(!item.isChecked());
    }
    //This is the trick here!!!!
    popupMenu.show();
    return true;
    }

});

Вы можете попробовать этот трюк со своим кодом! Вот как я это сделал. :)

person ThePatrickStar    schedule 08.07.2015

Ответ Оливера выше (https://stackoverflow.com/a/31727213/2423194) вызвал сбой и его сообщение сказал мне использовать MenuItemCompat вместо этого. После некоторой настройки этого кода он работает:

// Keep the popup menu open              
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(getContext()));
MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() {
    @Override
    public boolean onMenuItemActionExpand(MenuItem item) {
        return false;
    }

    @Override
    public boolean onMenuItemActionCollapse(MenuItem item) {
        return false;
    }
});

Спасибо, Оливер!

person Rock Lee    schedule 31.05.2017
comment
MenuItemCompat.OnActionExpandListener устарел. - person Sudheesh Mohan; 21.11.2017
comment
Да, это устарело. Используйте 1_ - person ; 21.02.2018

Попробуйте объявить PopupMenu глобально и вызвать popup.show(); перед возвратом true в функции onMenuItemClick.

person HYMXDEV    schedule 27.06.2015

Получил работу, добавив popup.show(); по нажатию кнопки и в конце щелчка.

final ImageButton layerButton = (ImageButton) findViewById(R.id.layers);
final PopupMenu popup = new PopupMenu(MapsActivity.this, layerButton);
popup.getMenuInflater().inflate(R.menu.toolbar_menu, popup.getMenu());

layerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //Here
            popup.show();

            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    handleClicksOnCheckBoxes(item);

                    return true;

                }

            });

            //And here
            popup.show();


        }
    });

Однако это не оптимальное решение, потому что если в списке так много элементов, что можно будет прокручивать список, то при нажатии на элемент список будет прокручиваться вверх.

person Marius Kohmann    schedule 28.03.2016

В вашем случае R.id.checkbox_item

return false;

Это сообщит системе, что событие еще не было обработано, и не закроет меню. См. ЗДЕСЬ

person Bojan Kseneman    schedule 19.04.2015
comment
Где вы слушаете его проверенное изменение состояния? - person Bojan Kseneman; 19.04.2015
comment
Я еще ничего не делал с этим событием click/check, пока оно не перестанет закрывать всплывающее меню. - person Sushant; 19.04.2015