0
votes

I'm trying to find a way to create a floating context menu when an item in my fragment's popup menu is long-pressed. When the menu icon in my layout is clicked, the popup menu appears and displays a list of files stored in a local directory to the app. When one of these files are long-pressed, i'd like a floating context menu to appear that gives the user the option of renaming or deleting the selected file.

According to the Android developer guide, floating context menus can be generated by passing a View (such as a ListView) into registerForContextMenu(). The programmer must then implement onCreateContextMenu() in the desired Activity or Fragment, i.e:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context_menu, menu);
}

I'm confused because registerForContextMenu() accepts a View as a parameter, but I'm trying to register the context menu to all the items in my Popup Menu instead of something like a ListView or a GridView. I've included my PopupMenu code below. How can I achieve a floating context menu when my popup menu items are long-pressed?

EDIT: This is my new code, which throws a nullpointer exception on the "View popupMenuItemView =" line

trackSelectButton = (Button) v.findViewById(R.id.trackSelect);
    trackSelectButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            trackListing = getTrackNames();
            PopupMenu popup = new PopupMenu(getActivity(), v);
            for (int i = 0; i < trackListing.length; i++) {      //add a menu item for each existing track
                popup.getMenu().add(0,i,0,trackListing[i].getName());    //my attempt to create a resource id (parameter #2) while adding the menu item 
                popup.getMenu().findItem(i).getActionView().setTag(i);   //my attempt to set a tag to a menu item
                View popupMenuItemView = getActivity().getWindow().getDecorView().findViewById(i); //nullpointer exception thrown here!
                registerForContextMenu(popupMenuItemView); //never reached due to crash 
            }

            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.new_track:
                            trackSelectButton.setText("...");
                            Toast.makeText(getActivity(), "Name your new track.", Toast.LENGTH_SHORT).show();
                            txtTrackName.setVisibility(txtTrackName.VISIBLE);
                            return true;
                        default:
                            selectedTrackName = (item.getTitle().toString());
                            trackSelectButton.setText(selectedTrackName);
                            for (int i = 0; i < trackListing.length; i++) {      //add a menu item for each existing track
                                if (trackListing[i].getName().equals(selectedTrackName)) {
                                    selectedTrack = trackListing[i];
                                    AudioRecorder.setFile(selectedTrack);
                                }
                            }
                            return true;
                    }
                }
            });

            MenuInflater popupInflater = popup.getMenuInflater();
            popupInflater.inflate(R.menu.popup_menu_track_selection, popup.getMenu());
            popup.show();
        }
    });
1

1 Answers

0
votes

I don't think there is a way to set a long click listener on the entire menu. I would suggest registering each item of your popup menu for context menu individually.

You can use the following to get the View of each menu item in your menu using the IDs you set in your menu xml:

View menuItemView = getActivity().getWindow().getDecorView().findViewById(R.id.item_id);

then pass this to registerForContextMenu.

registerForContextMenu(menuItemView)

Do that for each menu item then in your overridden onContextItemSelected(MenuItem item) you can use a switch on item.getItemId() to add logic for each item based on its ID.

EDIT Since you're adding the menu items programmatically, it would be better to assign a tag to the MenuItem's view. After creating the MenuItem You can get the view by menuItem.getActionView().setTag(whatever). Then use menuItem.getActionView().getTag() in onContextItemSelected