Android Menu 添加 Icon 無效問題的解決


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.printStackTrace(); } } } 

Xamarin.Android Code:

using Android.App; using Android.Views; using Android.OS; using Android.Support.V7.App; using Android.Widget; using Toolbar = Android.Support.V7.Widget.Toolbar; using Android.Media; using Android.Runtime; namespace HelloToolbar { [Activity(Label = "Support v7 Toolbar", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : MyBaseActivity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.main); var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar); //Toolbar will now take on default actionbar characteristics SetSupportActionBar(toolbar); SupportActionBar.Title = "Hello from Appcompat Toolbar"; var toolbarBottom = FindViewById<Toolbar>(Resource.Id.toolbar_bottom); toolbarBottom.Title = "Photo Editing"; toolbarBottom.InflateMenu(Resource.Menu.photo_edit); toolbarBottom.MenuItemClick += (sender, e) => { Toast.MakeText(this, "Bottom toolbar pressed: " + e.Item.TitleFormatted, ToastLength.Short).Show(); }; FindViewById<ImageView>(Resource.Id.image).Click += (sender, e) => { //StartActivity(typeof(CanvasActivity)); }; } /// <Docs>The options menu in which you place your items.</Docs> /// <returns>To be added.</returns> /// <summary> /// This is the menu for the Toolbar/Action Bar to use /// </summary> /// <param name="menu">Menu.</param> public override bool OnCreateOptionsMenu (IMenu menu) { MenuInflater.Inflate (Resource.Menu.home, menu); return base.OnCreateOptionsMenu (menu); } public override bool OnOptionsItemSelected (IMenuItem item) { Toast.MakeText(this, "Top ActionBar pressed: " + item.TitleFormatted, ToastLength.Short).Show(); return base.OnOptionsItemSelected (item); } public override bool OnMenuOpened(int featureId, IMenu menu) { System.Diagnostics.Debug.WriteLine(featureId); if (menu != null) { var javaObj = (Java.Lang.Object)menu; var javaClass = javaObj.Class; if (javaClass.SimpleName.EndsWith("MenuBuilder")) { try { Java.Lang.Reflect.Method m = javaClass.GetDeclaredMethod("setOptionalIconsVisible", new Java.Lang.Class[] { Java.Lang.Boolean.Type }); m.Accessible = true; m.Invoke(javaObj, new Java.Lang.Object[] { true }); } catch (Java.Lang.NoSuchFieldException e) { System.Console.WriteLine("onMenuOpened:{0}", e.ToString()); } } } return base.OnMenuOpened(featureId, menu); } } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM