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

问题描述:

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

根据Android developer guide,可以通过将View(如ListView)传递到registerForContextMenu()中来生成浮动上下文菜单。那么程序员必须实现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代码。当我的弹出式菜单项被长时间按下时,如何才能实现浮动上下文菜单?

编辑:这是我的新代码,它抛出一个空指针异常的“查看popupMenuItemView =”行

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

我不认为有一种方法来设置一个长点击监听器整个菜单。我建议单独为上下文菜单注册每个弹出式菜单项。

您可以使用下面的方法获得你的菜单中的每个菜单项的查看使用您设置的ID在你的菜单中的xml:

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

然后它传递给registerForContextMenu。

registerForContextMenu(menuItemView) 

做到这一点对每个菜单项,然后在您的重写onContextItemSelected(菜单项的项目),你可以使用item.getItemId()开关添加逻辑基于其ID的每个项目。

编辑 既然你编程添加菜单项,这将是更好地分配标签的菜单项的观点。创建MenuItem之后您可以通过menuItem.getActionView().setTag(whatever)获取视图。然后使用menuItem.getActionView().getTag()onContextItemSelected

+0

由于我动态创建一个弹出菜单项每次打开菜单(填充文件中找到的文件)我从来没有设置通过XML的菜单ID为弹出菜单项。每次生成我的弹出式菜单时,是否需要将R.ids分配给菜单项?或者它们以某种方式自动生成? – Cody

+0

@Cody在这种情况下,将一个标签分配给MenuItem的视图会更好 - 请参阅编辑 –

+0

您能否在您的答案中提供更完整的示例?我很困惑,现在我试图使用popup.getMenu()。add(0,i,0,trackListing [i] .getName());和popup35.getMenu()。findItem(i).getActionView()。setTag(i);和 popup.getMenu()。在我调用registerForContextMenu()之前设置每个菜单项的标签,但这看起来不正确。我应该传递给registerForContextMenu,标签? – Cody