解决Android 4.0以上版本中OptionsMenu菜单不显示ICON图标的问题

  在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,这样就可以在菜单中显示添加的图标了;

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
  setIconEnable(menu, true);   //调用这句实现显示ICON

  menu.add("新增记事").setIcon(R.drawable.add);
  menu.add("记事列表").setIcon(R.drawable.list);
  menu.add("分类管理").setIcon(R.drawable.category);
  menu.add("官方网站").setIcon(R.drawable.web);
  menu.add("关于").setIcon(R.drawable.about);
  menu.add("退出").setIcon(R.drawable.exit);

  return super.onCreateOptionsMenu(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();
  }
}
时间: 2024-08-11 03:32:49

解决Android 4.0以上版本中OptionsMenu菜单不显示ICON图标的问题的相关文章

在低于android 5.0的版本中ActionBar不显示

我从ABS切换到AppCompat与Material theme(仅适用于API21) 我的配置文件如下: <application android:theme="@style/AppStyle" <-- values folder --> <style name="AppStyle" parent="@style/AudioRecTheme"> <style name="AudioRecTheme&

从源码剖析PopupWindow 兼容Android 6.0以上版本点击外部不消失

PopupWindow可以说是Google坑最多的一个控件,使用PopupWindow的时候没有遇到几个坑你都不好意思说你用过它,说一个可能大多数人都遇到过的一个坑:那就是我们想触摸PopupWindow 以外区域就隐藏PopupWindow,理论上我们只需要调用 setOutsideTouchable(ture)设置为ture就可以了,但是实际上只设置这个属性是不行的,必须设置背景,也就是说要和setBackgroundDrawable(Drawable background)同时使用才有效,

android 4.0之前版本出现JSONException异常

今天在调试解析服务器传过来的JSON数据时,在2.3.7的手机上报了下面这样一个异常. 08-07 22:00:29.597: W/System.err(7610): org.json.JSONException: Value  of type java.lang.String cannot be converted to JSONArray 而在android4.0版本以上的手机上调试是没有问题的,从而去看了下android4.0 JSONArray源码,发现有如下变化 从对比图片来看,问题

我的Android进阶之旅------&gt;如何解决Android 5.0中出现的警告: Service Intent must be explicit:

1.错误描述 今天在Android4.4 的小米4手机上运行我的程序的时候没有报错,而在Android 5.1的华为P7上运行我的程序的时候报了以下的错误,错误提示如下: E/AndroidRuntime(12500): FATAL EXCEPTION: main E/AndroidRuntime(12500): Process: com.xtc.watch, PID: 12500 E/AndroidRuntime(12500): java.lang.IllegalArgumentExcepti

解决Android 5.0中出现的警告:Service Intent must be explicit

extends:http://www.eoeandroid.com/thread-568853-1-1.html 本帖最后由 469874851 于 2015-3-11 18:15 编辑 有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动.而android源码是这样写的(源码位置:sdk/source

如何解决Android 5.0中出现的警告:Service Intent must be expli

有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动. 而android源码是这样写的(源码位置:sdk/sources/android-21/android/app/ContextImpl.java): private void validateServiceIntent(Intent service

[Android分享] 如何解决Android 5.0中出现的警告:Service Intent must be explicit

Android 5.0程序运行报Service Intent must be explicit错误,原因是5.0的service必须显式调用 改成 Intent intent = new Intent(mContext, IService.class); 或者Intent intent = new Intent(): intent.setclass(xx.xx,xx.xx): 网上说的如下方式是不可行的: Intent intent = new Intent("com.xx.xx.Service

解决Android 6.0获取wifi Mac地址为02:00:00:00:00:00问题【转】

本文转载自:http://www.jb51.net/article/128398.htm 这篇文章主要介绍了Android 6.0获取wifi Mac地址为02:00:00:00:00:00的解决方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下 前言: 之前项目比较旧,手机版本还比较低,还使用eclipse开发.用到了需要获取手机wifi Mac地址.使用了如下代码: // Android 6.0之前的版本可以用的方法(模拟器可以使用) private String getMacAddrO

[翻译]Android 5.0之应用中实现材料设计—Material Design

上午的时候在刷Google+,看到了Abraham Williams转发了一篇强文,是Android Developers网站新发的一篇博客—Implementing Material Design in your Android App.觉得很前卫,对于新发布的Android版本号Android 5.0是一个很好的学习和了解的机会,所以就花了些时间把它翻译了下来,希望对自己.对其它人有所启发. 因为翻译Android开发博客和API也只是业余爱好,水平有限,其中不免有不准确的地方,所以把原文地