目的:為應用實作長按清單項删除crime記錄功能。
3.0版本前(舊)是在浮動上下文菜單實作
3.0版本後(新)在上下文操作欄呈現。
為相容API級别,必須定義一種菜單資源,和兩組回調方法(新舊各一種)。
18.2.1菜單資源:在res/menu中建立菜單資源檔案。
<?xml version="1.0" encoding="utf-8"?>
<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"/>
</menu>
執行個體化生成上下文菜單的方法:public void onCreateContextMenu(ContextMenu menu,View v,ContextMenu.ContextMenuInfo menuInfo)
建立上下文菜單:
//由于這個菜單回調方法不接受MenuInflater執行個體參數,是以先獲得它,然後調用inflate()方法進行上下文菜單的填充。
public void onCreateContextMenu(ContextMenu menu,View v,ContextMenu.ContextMenuInfo menuInfo){
getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu);
}
18.2.2為上下文登記視圖:Fragment方法:public void registerForContextMenu(View view)
如果想為任意清單項登記,直接登記ListView即可,裡面的各個清單項會自動登記。
//在onCreateView方法中引用并登記ListView:
ListView listView = (ListView)v.findViewById(android.R.id.list);
registerForContextMenu(listView);
//使用android.R.id.list擷取ListFragment管理的ListView,是因為ListFragment的getListView方法隻能在onCreateView方法後使用。
18.2.3響應菜單項選擇:
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()).deleteCrimes(crime);
adapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
//因ListView是AdapterView的子類,是以getMenuInfo傳回AdapterContextMenuInfo執行個體。擷取選取項的位置,進行操作,還要adapter進行視
圖的重新整理。
18.3實施上下文操作模式。
上下文操作欄的類和方法不适合于舊系統,是以要分隔開
18.3.1視圖清單的多選模式。
很簡單,隻需要将ListView選擇模式設定為CHOICE_MODE_MULTIPE_MODAL即可
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.HONEYCOMB){
registerForContextMenu(listView);
}else{
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
18.3.2清單視圖操作模式回調方法
listView.setMultiChoiceModeListener(new MultiChoiceModeListener(){
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
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.deleteCrimes(adapter.getItem(i));
}
}
mode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
為了突出顯示,改變已選中視圖的顯示背景
· 基于視圖的狀态,可使用state list drawable資源改變背景。(好神奇!)它是與螢幕密度無關,是以建立在drawable目錄下就可以
了,不需要帶修飾符。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_activated="true"
android:drawable="@android:color/darker_gray"
/>
</selector>
根元素為selector。
還要對該xml進行引用。
android:background="@drawable/background_activated"
以上的調回方法隻适用于listView和gridview視圖,其他的視圖首先要設定一個實作了View.OnLongClickListener接口的監聽器。監聽器内部
要自己調用Activity.startActionMode(ActionMode.Callback)方法建立一個ActionMode執行個體,首先建立一個參數的執行個體,然後調用方法,或者适用匿名
内部類的方式調用就好。
然後就是學習了針對新舊系統是用回退還是複制操作。這沒什麼可說的。
最後就是挑戰練習,需要我自個來定義選項菜單的定義和操作。
今天就先寫到這吧。
現在還是很難記住剛學的東西啊,要時不時的回頭看,但更要向下面學。
目前的選擇是先看完這本書,然後我再去打算看看老羅的視訊。話說視訊好像好長啊!不過沒關系,我有的,就是時間。