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應用程序中來為列表中的每一個注釋添加一個上下文菜單:
- 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) 方法:
- registerForContextMenu(getListView());
registerForContextMenu(getListView());
記住,你可以傳遞任何視圖對象來注冊一個上下文菜單。這里,getListView()返回這個被用於Notepad應用程序的列表活動ListActivity中的列表視圖對象。這樣,這個列表中的任何item都被注冊到這個上下文菜單。