Android Menu 添加 Icon 無效問題
問題分析
在 Android4.0
系統中,創建菜單 Menu
,通過setIcon
方法給菜單添加圖標是無效的,圖標沒有顯出來,但在 Android 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
,這就是為什么給菜單設置圖標沒有效果的原因
解決思路
所以,只要我們在創建 Menu
時通過調用 setOptionalIconsVisible
方法設置 mOptionalIconsVisible
為 true
就可以了。
難點:要想調用該方法,就需要創建 MenuBuilder
對象,但是,我們是無法在開發的應用程序中創建 MenuBuilder
這個對象的 -- MenuBuilder
為系統內部的框架類
這時候就需要考慮用反射了,在代碼運行創建菜單的時候通過反射調用 setOptionalIconsVisible
方法設置mOptionalIconsVisible
為 true
,然后在給菜單添加 Icon
,這樣就可以在菜單中顯示添加的圖標了
Java Code:
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.