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代码
- 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);
- }
- }
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代码
- registerForContextMenu(getListView());
registerForContextMenu(getListView());
记住,你可以传递任何视图对象来注册一个上下文菜单。这里,getListView()返回这个被用于Notepad应用程序的列表活动ListActivity中的列表视图对象。这样,这个列表中的任何item都被注册到这个上下文菜单。
Android——长按弹出菜单、获取当前所按的item的信息