在Android4.0系統中,創建菜單Menu,通過setIcon方法給菜單添加圖標是無效的,圖標沒有顯出來,2.3系統中是可以顯示出來的。這個問題的根本原因在於4.0系統中,涉及到菜單的源碼類 MenuBuilder做了改變,該類的部分源碼如下:
- public class MenuBuilder implements Menu {
- ...
- private boolean mOptionalIconsVisible = false;
- ....
- void setOptionalIconsVisible(boolean visible) {
- mOptionalIconsVisible = visible;
- }
- boolean getOptionalIconsVisible() {
- return mOptionalIconsVisible;
- }
- ...
- }
上面的代碼中,mOptionalIconsVisible成員初始值默認爲false,這就是爲什麼給菜單設置圖標沒有效果的原因;所以,只要我們在創建菜單時通過調用setOptionalIconsVisible方法設置mOptionalIconsVisible爲true就可以了;這時候問題來了,要想調用該方法,就需要創建MenuBuilder對象,但是,我們是無法在開發的應用程序中創建MenuBuilder這個對象的(MenuBuilder爲系統內部的框架類);
這時候就需要考慮用反射了,在代碼運行創建菜單的時候通過反射調用setOptionalIconsVisible方法設置mOptionalIconsVisible爲true,然後在給菜單添加Icon,這樣就可以在菜單中顯示添加的圖標了;
代碼實現如下:
- package com.stevenhu.mie;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MenuItem;
- public class MainActivity extends Activity
- {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
- //運行時,參數Menu其實就是MenuBuilder對象
- Log.d("MainActivity", "menu--->" + menu);
- /*利用反射機制調用MenuBuilder的setOptionalIconsVisible方法設置mOptionalIconsVisible爲true,
- * 給菜單設置圖標時纔可見
- */
- setIconEnable(menu, true);
- MenuItem item1 = menu.add(0, 1, 0, R.string.item1);
- item1.setIcon(R.drawable.camera);
- MenuItem item2 = menu.add(0, 1, 0, R.string.item2);
- item2.setIcon(R.drawable.dial);
- MenuItem item3 = menu.add(0, 1, 0, R.string.item3);
- item3.setIcon(R.drawable.sms);
- return super.onCreateOptionsMenu(menu);
- }
- @Override
- public boolean onPrepareOptionsMenu(Menu menu)
- {
- // TODO Auto-generated method stub
- return super.onPrepareOptionsMenu(menu);
- }
- //enable爲true時,菜單添加圖標有效,enable爲false時無效。4.0系統默認無效
- private void setIconEnable(Menu menu, boolean enable)
- {
- try
- {
- Class<?> clazz = Class.forName("com.android.internal.view.menu.MenuBuilder");
- Method m = clazz.getDeclaredMethod("setOptionalIconsVisible", boolean.class);
- m.setAccessible(true);
- //MenuBuilder實現Menu接口,創建菜單時,傳進來的menu其實就是MenuBuilder對象(java的多態特徵)
- m.invoke(menu, enable);
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }