例如長按删除功能就是一種上下文操作,上下文操作與某個特定的螢幕視圖(單個清單項)而非整個螢幕相關聯
一:在res/menu下建立菜單資源檔案
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_item_delete_crime"
android:icon="@android:drawable/ic_menu_delete"
android:title="@string/delete_crime"
></item>
</menu>
二:建立上下文菜單和響應
onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)建立
onContextItemSelected(MenuItem item)響應
建立上下文菜單:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu);
}
預設情況下,長按視圖不會觸發上下文菜單的建立,要觸發上下文菜單的建立,就要在onCreateView中調用Fragment的registerForContextMenu(View view)登記一個視圖
ListView listView = (ListView) v.findViewById(android.R.id.list);
registerForContextMenu(listView);
響應上下文菜單選擇
調用onContextItemSelected(MenuItem item),并在方法中編寫響應邏輯,例如我要進行删除
@Override
public boolean onContextItemSelected(MenuItem item){
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int position = info.position;
CrimeAdapter adapter = (CrimeAdapter) getListAdapter();
Crime crime = adapter.getItem(position);
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
CrimeLab.get(getActivity()).delete(crime);
adapter.notifyDataSetChanged();
return true;
default:
break;
}
return super.onContextItemSelected(item);
}
三:如果要實作清單視圖的多選操作(例如長按可以選多多個item删除)
1.在onCreateView中設定清單視圖的選擇模式為CHOICE_MODE_MULTIPLE_MODAL
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
此時已經實作了清單視圖的多選模式了
2.清單視圖的操作模式回調方法
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// TODO Auto-generated method stub
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.crime_list_item_context, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
CrimeAdapter adapter = (CrimeAdapter) getListAdapter();
CrimeLab crimeLab = CrimeLab.get(getActivity());
for(int i = adapter.getCount() - 1; i >= 0; i--){
if(getListView().isItemChecked(i)){
crimeLab.delete(adapter.getItem(i));
}
}
mode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
}
});
為視圖實作AbsListView.MultiChoiceModeListener接口的監聽器,該接口包含onItemCheckedStateChanged(Action mode, int position, long id, boolean checked)這個方法,每當視圖被選中或者撤銷的都會觸發此方法,但由于AbsListView.MultiChoiceModeListener接口包含了ActionMode.callback接口,是以還要實作一下幾個方法:
1.public abstract boolean onCreateActionMode(ActionMode mode, Menu menu)
在ActionMode對象建立後使用,執行個體化菜單并顯示在上下文操作欄的地方
2.public boolean onPrepareActionMode(ActionMode mode, Menu menu)
上下文需要重新整理顯示新資料時調用
3.public boolean onActionItemClicked(ActionMode mode, MenuItem item)
使用者選中某個菜單項操作時調用,響應上下文菜單操作的地方
4.public void onDestroyActionMode(ActionMode mode)
一般在actionmode銷毀時選用
四:此時可以實作多選操作了,但是長按已選背景并沒有改變,導緻使用者不能區分
首先,在res/drawable目錄下建立background_activated.xml檔案
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_activated="true"
android:drawable="@android:color/darker_gray">
</item>
</selector>
state_activated為true,表明當引用該資源的視圖(此處為listview)處于激活狀态時,則使用android:drawable屬性所指定的資源。
如果為false,則隻要視圖處于未被激活時,android:drawable屬性所指定的資源都會被使用
然後在原來視圖(此處為listview)加上屬性android:background="@drawable/background_activated"
此時長按清單項,被選中的listItem就會顯示darker_gray的顔色
思考:
以上所說的上下文操作欄可以完美得應用于ListView和GirdView,但是對于其它視圖,是不支援的。
對于其他視圖,我們首先設定一個實作View.OnLongClickListener接口的監聽器,然後在監聽器體内,調用Activity的startActionMode()建立一個actionMode執行個體,MultiChoiceModeListener接口中的ActionMode執行個體是自動建立的,startActionMode()需要一個實作ActionMode.callBack接口對象作為參數,是以建立一個ActionMode.callBack接口的實作,自然也要實作那四個方法:
1.public abstract boolean onCreateActionMode(ActionMode mode, Menu menu)
2.public boolean onPrepareActionMode(ActionMode mode, Menu menu)
3.public boolean onActionItemClicked(ActionMode mode, MenuItem item)
4.public void onDestroyActionMode(ActionMode mode)