android的一個activity可以再選中某項之後按menu鍵彈出特定的菜單,也就是動态菜單。動态菜單的實作是靠menu類中的addintentoptions函數實作的,具體的聲明如下:
int android.view.menu.addintentoptions(
int groupid,
int itemid,
int order,
componentname caller,
intent[] specifics,
intent intent,
int flags,
menuitem[] outspecificitems)
這個函數是用來動态産生option menu的
函數參數分析:
1. groupid 就是菜單組的編号;
2. itemid (可以讓其為0)
3. order 菜單順序,可以不考慮
4. caller 就是發起activity的activity
5. specifics 以action+uri的具體方式來增加激活相應activity的菜單項
6. intent 以categroy+uri這種一般形式來增加激活相應activity的菜單項
參數intent和specifics的差別是,一個用categroy+uri來比對activity,一個用action+uri來比對 activity。
8. outspecificitems 這個是傳回的menuitem值,對應以specifics方式比對的菜單項。
下面以android sdk中notepad的例子來說明其用法。
來看這個例子中的noteslist.java 檔案中的public boolean onprepareoptionsmenu(menu menu)函數,這個函數會在設定普通option menu菜單項的的oncreateoptionsmenu函數之後調用,這個函數的主要部分是如下代碼:
view plaincopy to clipboardprint?
1. uri uri = contenturis.withappendedid(getintent().getdata(), getselecteditemid());
2.
3.
4. intent[] specifics = new intent[1];
5. specifics[0] = new intent(intent.action_edit, uri);
6. menuitem[] items = new menuitem[1];
7.
8.
9. intent intent = new intent(null, uri);
10. intent.addcategory(intent.category_alternative);
11. menu.addintentoptions(menu.category_alternative, 0, 0, null, specifics, intent, 0,
12. items);
uri uri = contenturis.withappendedid(getintent().getdata(), getselecteditemid()); intent[] specifics = new intent[1]; specifics[0] = new intent(intent.action_edit, uri); menuitem[] items = new menuitem[1]; intent intent = new intent(null, uri); intent.addcategory(intent.category_alternative);
menu.addintentoptions(menu.category_alternative, 0, 0, null, specifics, intent, 0, items);
其中 contenturis.withappendedid(getintent().getdata(), getselecteditemid())會得到選中項的資訊,這個資訊将會作用比對用的intent的
data部分。
specifics[0] = new intent(intent.action_edit, uri)在這裡是這個意思:到androidmenifest.xml中去找activity, 如果有某個activity的<intent-
filter>項的action和data與intent.action_edit和相應的uri比對,就為這個activity添加一個菜單項,菜單項的顯示名稱從相應 activity的
android:label項得來。
intent intent = new intent(null, uri);
intent.addcategory(intent.category_alternative);
是這個意思:到androidmenifest.xml中去找activity,如果有某些 activity的<intent-filter>項的category和data與
intent.category_alternative和相應的uri比對,就為這些activity分别添加菜單項,菜單項的顯示名稱從相應activity的android:label項
得來。
下面可以做個試驗,在androidmenifest.xml中建立一個activity myadd
1. <activity android:name="myadd" android:label="@string/title_myadd"
2. android:windowsoftinputmode="statevisible">
3. <intent-filter android:label="@string/resolve_myadd">
4. <action android:name="com.android.notepad.action.myadd" />
5. <category android:name="android.intent.category.alternative" />
6. <data android:mimetype="vnd.android.cursor.item/vnd.google.note" />
7. </intent-filter>
8. </activity>
<activity android:name="myadd" android:label="@string/title_myadd" android:windowsoftinputmode="statevisible"> <intent-filter android:label="@string/resolve_myadd"> <action android:name="com.android.notepad.action.myadd" /> <category android:name="android.intent.category.alternative"
/> <data android:mimetype="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> </activity>
寫好該activity的layout和實作後,選中noteslist中的一項後,點 menu可以看到菜單中多出了一項,點選可以切換到該activity。
這是以函數中intent比對的菜單項,當然也可以用specifics來比對。下面示例:
删除掉myadd這個activity中的 <category android:name="android.intent.category.alternative" />,這時該activity已經與intent不比對了,
再将onprepareoptionsmenu 函數中的代碼改成如下:
1. intent[] specifics = new intent[2];
2. specifics[0] = new intent(intent.action_view, uri);
3. specifics[1] = new intent("com.android.notepad.action.myadd",uri);
4. menuitem[] items = new menuitem[2];
intent[] specifics = new intent[2]; specifics[0] = new intent(intent.action_view, uri); specifics[1] = new intent("com.android.notepad.action.myadd",uri); menuitem[] items = new menuitem[2];
選中一項點菜會發現,動态菜單又回來了,不過這次是用specific來比對的。