如何防止点击复选框时弹出菜单关闭

15

我在网上搜索了很多,但没有关于如何防止弹出菜单关闭的内容。

每当我点击复选框或其他弹出菜单项时,弹出菜单都会自动关闭。我该如何防止用户在弹出菜单中勾选/取消勾选复选框时关闭它。

我是在操作栏菜单项的单击事件中显示弹出菜单的。

//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;
}

复选框代码在哪里,请发布完整的代码。 - Ajit Kumar Dubey
请检查我的更新代码(notification_item - checkbox_item)。checkbox_item是可选中的弹出菜单项。在它停止关闭弹出菜单之前,我还没有对它的点击/选中事件做任何处理。 - Sushant
@sushant- 在v中保存哪个视图? - Ajit Kumar Dubey
主菜单.xml(操作栏上的菜单项) - Sushant
@sushant- 在这种情况下,您必须创建自定义视图,然后您可以处理您想要的所有内容。 - Ajit Kumar Dubey
6个回答

38

当改变可选菜单项的选中状态时,使用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;
    }
});

它给了我一个错误,说我需要使用MenuItemCompat。我在下面的答案中调整了代码(https://dev59.com/vl0a5IYBdhLWcg3w-8_a#44296077)。 - Rock Lee
对于像我这样的新手,请注意:这与XML行android:onClick="myHandler"冲突,因此您必须将其删除。 - Phlip
1
澄清一下:仅仅返回false是不够的,你还需要上面的其他行代码(setShowAsAction等)。 - arlomedia

5
这里的技巧是在菜单关闭后立即显示菜单。
以下是示例代码片段:
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;
    }

});

你可以尝试使用这个技巧来改进你的代码!这就是我使用它的方式。 :)

1

Oliver在上面的答案(链接https://dev59.com/vl0a5IYBdhLWcg3w-8_a#31727213)给了我一个崩溃,并告诉我要使用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;
    }
});

感谢 Oliver!


1
MenuItemCompat.OnActionExpandListener现在已经过时。 - Sudheesh Mohan
是的,它已经被弃用了。请使用item.setOnActionExpandListener - user5698345

0
尝试在全局声明PopupMenu并在onMenuItemClick函数中调用popup.show(),然后再返回true。

0

通过在按钮点击和点击结束时添加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();


        }
    });

然而,这不是最佳解决方案,因为如果列表具有许多项目以至于可能可以滚动列表,则单击项目时列表将滚动到顶部。


-1

在你的情况下,R.id.checkbox_item

return false;

这将告诉系统事件尚未处理,它不会关闭菜单。请参见此处


你在哪里监听它的选中状态改变? - Bojan Kseneman
直到弹出菜单停止关闭,我才会在其点击/检查事件上采取任何行动。 - Sushant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接