Android:长按弹出菜单项创建上下文菜单

时间:2016-06-09 04:41:35

标签: android xml menu contextmenu popupmenu

我正在尝试找到一种方法来创建浮动上下文菜单,当我的片段弹出菜单中的项目被长按时。单击布局中的菜单图标时,将出现弹出菜单,并显示存储在应用程序本地目录中的文件列表。当其中一个文件被长按时,我想要一个浮动的上下文菜单,让用户可以选择重命名或删除所选文件。

根据Android developer guide,可以通过将View(例如ListView)传递给registerForContextMenu()来生成浮动上下文菜单。然后程序员必须在所需的Activity或Fragment中实现onCreateContextMenu(),即:

@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);
}

我很困惑,因为registerForContextMenu()接受View作为参数,但我正在尝试将上下文菜单注册到我的弹出菜单中的所有项目,而不是ListView或GridView。我在下面包含了我的PopupMenu代码。当我的弹出菜单项被长按时,如何实现浮动上下文菜单?

编辑:这是我的新代码,它会在“View popupMenuItemView =”行

上抛出一个nullpointer异常
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 个答案:

答案 0 :(得分:0)

我认为没有办法在整个菜单上设置长按一下监听器。我建议单独为上下文菜单注册弹出菜单的每个项目。

您可以使用以下内容通过菜单xml中设置的ID获取菜单中每个菜单项的视图:

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

然后将其传递给registerForContextMenu。

registerForContextMenu(menuItemView)

为每个菜单项执行此操作,然后在重写的onContextItemSelected(MenuItem项)中,您可以使用item.getItemId()上的开关根据其ID为每个项添加逻辑。

修改 由于您是以编程方式添加菜单项,因此最好将标签分配给MenuItem的视图。创建MenuItem后,您可以按menuItem.getActionView().setTag(whatever)获取视图。然后在menuItem.getActionView().getTag()

中使用onContextItemSelected