首页 > 代码库 > Android——长按弹出菜单、获取当前所按的item的信息

Android——长按弹出菜单、获取当前所按的item的信息

ListView 中有多个选项,长按每个选项,都能弹出一个上下文菜单,并能获取所按选项的详细信息。

关键步骤:

 private static final int DELETE_ID = Menu.FIRST + 1;//使用Menu.FIRST常量而不使用其他常量的原因:程序封装的变量 用起来不占内存 程序读的快 不容易出错
 private static final int EDIT_ID=Menu.FIRST + 2;
 private static final int VIEW_ID=Menu.FIRST + 3;

1、在方法onCreate中为ListView注册上下文菜单(红字所示)

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.diary_list);
  mDbHelper = new DiaryDbAdapter(this);
  mDbHelper.open();
  renderListView();
  registerForContextMenu(getListView());//为每个项创建上下文菜单
 }

2、@Override                  //创建长按弹出式菜单,这是一个回调函数
 public void onCreateContextMenu(ContextMenu menu, View v,
   ContextMenuInfo menuInfo) {
  // TODO Auto-generated method stub
        super.onCreateContextMenu(menu, v, menuInfo);
     //添加菜单项
         menu.add(0, DELETE_ID, 1, R.string.menu_delete);                       
        menu.add(0, EDIT_ID, 2, R.string.menu_edit);
        menu.add(0, VIEW_ID, 3, R.string.menu_view);
 }

对菜单中的各项的响应:

public boolean onContextItemSelected(MenuItem item) {
     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 
     long id=info.id;//当前项的key标示,独一无二的
     int position=info.position;//当前项在ListView中的位置
   Cursor c = mDiaryCursor;
   c.moveToPosition(position);
   selected_id=id;
   selected_title=c.getString(c.getColumnIndex(DiaryDbAdapter.KEY_TITLE));
   selected_body=c.getString(c.getColumnIndex(DiaryDbAdapter.KEY_BODY));
   selected_created=c.getString(c.getColumnIndex(DiaryDbAdapter.KEY_CREATED));
         switch(item.getItemId()){

      case DELETE_ID:
          mDbHelper.deleteDiary(info.id);
    renderListView();
    return true;
         case EDIT_ID:

Intent i = new Intent(ActivityMain.this, ActivityDiaryEdit.class);
       i.putExtra(DiaryDbAdapter.KEY_ROWID, selected_id);
       i.putExtra(DiaryDbAdapter.KEY_TITLE, selected_title);
       i.putExtra(DiaryDbAdapter.KEY_BODY, selected_body);//从零开始返回指定列名称,如果不存在将抛出IllegalArgumentException 异常。
       startActivityForResult(i, ACTIVITY_EDIT);
       return true;
          
         case VIEW_ID:

AlertDialog.Builder builder=new AlertDialog.Builder(ActivityMain.this);
    builder.setTitle(selected_title+"("+selected_created+")");
    builder.setMessage(selected_body);
    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) {
      // TODO Auto-generated method stub
      dialog.dismiss();
     }
    });
    builder.show();
    return true;
         }
         return super.onContextItemSelected(item);

}

或者(转自http://wen66.iteye.com/blog/1208617 )

private ListView fileList;  

  •    
  • fileList.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {    
  •     
  •     @Override    
  •     public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo info) {    
  •         // TODO Auto-generated method stub    
  •         menu.setHeaderTitle(R.string.contentMenu);    
  •         menu.add(0, AndBoxConstant.OPEN, 0, R.string.open);    
  •         menu.add(0, AndBoxConstant.PROPERTIY, 6, R.string.properties);    
  •     }    
  • });    
  •    
  • @Override    
  • public boolean onContextItemSelected(MenuItem item) {    
  •     switch (item.getItemId()) {   
  •   
  •     case AndBoxConstant.OPEN:    
  •         .........    
  •         break;    
  •   
  •     case AndBoxConstant.PROPERTIY:    
  •         .........    
  •         break;    
  •   
  •     default:    
  •         break;    
  •     }    
  •     return super.onContextItemSelected(item);    
  • }  
  •   
  • fileList.setOnItemLongClickListener(new OnItemLongClickListener() {  
  •     @Override    
  •     public boolean onItemLongClick(AdapterView<?> ada, View view, int index, long longIndex) {    
  •         fileList.showContextMenu();    
  •         return true;    
  •     }    
  • });  

 

在处理长按时,注意的细节是把onItemLongClick返回设置为true,否则长按是会执行setOnItemClickListener。

=============================================================

上下文菜单Context Menu Android的上下文菜单在概念上和PC软件的右键菜单类似。当一个视图注册到一个上下文菜单时,执行一个在该对象上的“长按”(按住不动差不多两秒钟)动作,将出现一个提供相关功能的浮动菜单。上下文菜单可以被注册到任何视图对象中,不过,最常见的是用于列表视图ListView的item,在按中列表项时,会转换其背景色而提示将呈现上下文菜单。 (电话联系人列表提供了关于这个特性的一个很好的例子)。      注意:上下文菜单项不支持图标或快捷键。      为了创建一个上下文菜单,你必须重写这个活动的上下文菜单回调函数:onCreateContextMenu() 和onContextItemSelected()。在回调函数onCreateContextMenu()里,你可以通过使用一个add()方法来添加菜单项,或者通过扩充一个定义在XML中的菜单资源。然后,通过registerForContextMenu()为这个视图注册一个上下文菜单ContextMenu.  
比如,下面的代码可以被用到Notepad应用程序中来为列表中的每一个注释添加一个上下文菜单:  

Java代码 复制代码
  1. public void onCreateContextMenu(ContextMenu menu, View v,    
  2.                                 ContextMenuInfo menuInfo) {    
  3.    
  4.   super.onCreateContextMenu(menu, v, menuInfo);    
  5.   menu.add(0, EDIT_ID, 0, "Edit");    
  6.   menu.add(0, DELETE_ID, 0,  "Delete");    
  7.    
  8. }    
  9.       
  10. public boolean onContextItemSelected(MenuItem item) {    
  11.    
  12.   AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();    
  13.   switch (item.getItemId()) {    
  14.    
  15.   case EDIT_ID:    
  16.     editNote(info.id);    
  17.     return true;    
  18.    
  19.   case DELETE_ID:    
  20.     deleteNote(info.id);    
  21.     return true;    
  22.    
  23.   default:    
  24.     return super.onContextItemSelected(item);    
  25.   }    
  26. }  
public void onCreateContextMenu(ContextMenu menu, View v,                                  ContextMenuInfo menuInfo) {     super.onCreateContextMenu(menu, v, menuInfo);    menu.add(0, EDIT_ID, 0, "Edit");    menu.add(0, DELETE_ID, 0,  "Delete");   }      public boolean onContextItemSelected(MenuItem item) {     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();    switch (item.getItemId()) {     case EDIT_ID:      editNote(info.id);      return true;     case DELETE_ID:      deleteNote(info.id);      return true;     default:      return super.onContextItemSelected(item);    }  }

在onCreateContextMenu()中,除了给出将添加MenuItems的ContextMenu外,还需要给定选中的视图和一个上下文菜单信息ContextMenuInfo对象,该对象提供了选中对象的附加信息。在本例中,onCreateContextMenu()没做什么特别的事-只是添加了一些菜单项。
在onContextItemSelected() 回调函数中,我们从MenuItem中请求AdapterContextMenuInfo,该对象提供当前选中项的信息。我们从中所要的只是这个选中项的列表ID,所以无论编辑还是删除一个注释,我们通过这个对象的AdapterContextMenuInfo.info字段来找到该ID。这个ID被传递给editNote() 和deleteNote()方法来执行相应的动作。  
现在,要为一个列表视图中的所有项注册上下文菜单,我们可以传递整个的列表视图对象给registerForContextMenu(View) 方法:  

Java代码 复制代码 
  1. registerForContextMenu(getListView());    
registerForContextMenu(getListView());  

   记住,你可以传递任何视图对象来注册一个上下文菜单。这里,getListView()返回这个被用于Notepad应用程序的列表活动ListActivity中的列表视图对象。这样,这个列表中的任何item都被注册到这个上下文菜单。