Search code examples
androidpopupmenu

Popup menu is accumulating occurrences (not dismissing properly)


I have a strange bug in my app. I have a RecyclerView containing list items with an icon for an overflow menu. See below.enter image description here

The problem occurs when I touch outside of the menu (to cancel it). The next time I select the menu it renders 2 menus. This continues for as many times as I go through the motions. See below. enter image description here

I can't figure out why this is happening. Here is my code for displaying the menu in a ViewHolder's list item:

final PopupMenu popupMenu = new PopupMenu(mContext, mOptionsMenu);

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

                        popupMenu.inflate(R.menu.menu_edit_delete_dq_competitor);

                        Menu menu = popupMenu.getMenu();
                        MenuItem edit = menu.findItem(R.id.edit);
                        MenuItem delete = menu.findItem(R.id.delete);
                        MenuItem dq = menu.findItem(R.id.dq);
                        MenuItem undoDq = menu.findItem(R.id.undo);

                        // change options if this competitor is DQ
                        if (competitor.getStatus() == Status.DQ) {
                            edit.setVisible(false);
                            delete.setVisible(false);
                            dq.setVisible(false);
                            undoDq.setVisible(true);
                        }
                        popupMenu.show();
                    }
                });

And here is my code for when a menu item is selected:

      popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        FragmentManager manager = getActivity().getSupportFragmentManager();
                        switch (item.getItemId()) {
                            case R.id.edit:
                                // todo finish this
//                                Intent intent = CompetitorInMatchForm.editIntent(mContext, competitor, true);
//                                startActivity(intent);
                                break;
                            case R.id.delete:
                                CompetitorStatusInMatchDialog deleteDialog = CompetitorStatusInMatchDialog.newInstance(competitor, "delete", getAdapterPosition());
                                deleteDialog.setTargetFragment(CompsInMatchFragment.this, REQUEST_ACTION);
                                deleteDialog.show(manager, DELETE_COMP_FROM_MATCH);
                                break;
                            case R.id.dq:
                                CompetitorStatusInMatchDialog dqDialog = CompetitorStatusInMatchDialog.newInstance(competitor, "dq", getAdapterPosition());
                                dqDialog.setTargetFragment(CompsInMatchFragment.this, REQUEST_ACTION);
                                dqDialog.show(manager, DELETE_COMP_FROM_MATCH);
                                break;
                            case R.id.undo:
                                CompetitorStatusInMatchDialog undoDialog = CompetitorStatusInMatchDialog.newInstance(competitor, "undo", getAdapterPosition());
                                undoDialog.setTargetFragment(CompsInMatchFragment.this, REQUEST_ACTION);
                                undoDialog.show(manager, DELETE_COMP_FROM_MATCH);
                                break;
                            default:
                                popupMenu.dismiss();
                        }

                        return true;
                    }
                });

Any help identifying why the dialog accumulates menu occurrences would be great.I have use popup menus before without this problem. I expect that it is dismissed when you touch outside of the menu.


Solution

  • That's because you inflate the menu inside the onClick listener, thus actually adding all the elements every time the menu is displayed.

    If you expect that dismiss will remove the items from the menu, that's wrong: it will only hide the popup.

    You can move this line outside of the listener:

    popupMenu.inflate(R.menu.menu_edit_delete_dq_competitor);
    

    like this:

    final PopupMenu popupMenu = new PopupMenu(mContext, mOptionsMenu);
    popupMenu.inflate(R.menu.menu_edit_delete_dq_competitor);