本文转载自:

http://blog.csdn.net/stevenhu_223/article/details/9705173

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

通过上面的代码,就可以实现在Android4.0系统中设置菜单的Icon有效了;

Demo下载链接地址:http://download.csdn.net/detail/stevenhu_223/5854207

解决android4.0系统中菜单(Menu)添加Icon无效问题的更多相关文章

  1. 关于解决android4.0系统中菜单无法添加Icon的问题

    在Android4.0系统中,创建菜单Menu,然后通过setIcon方法给菜单添加图标是无效的,图标不会显出来,而之前的系统中是可以显示出来的.这个问题的根本原因在于4.0系统中,涉及到菜单的源码类 ...

  2. Android应用图标微技巧,8.0系统中应用图标的适配

    现在已经进入了2018年,Android 8.0系统也逐渐开始普及起来了.三星今年推出的最新旗舰机Galaxy S9已经搭载了Android 8.0系统,紧接着小米.华为.OV等国产手机厂商即将推出的 ...

  3. 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”

    通过源码了解ASP.NET MVC 几种Filter的执行过程   一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...

  4. 如何在RedHat 7.0系统中安装mysql 5.7.22

    如何在RedHat 7.0系统中安装mysql 5.7.22 今天给大家介绍一下如何安装mysql5.7,在安装之前,首先要查看的是,你的系统中有没有已经安装过的情况.键入rpm -qa|grep m ...

  5. 深入浅出-Android系统移植与平台开发(一)- Android4.0系统的下载与编译

    作者:唐老师,华清远见嵌入式学院讲师. 一.Android4.0系统的下载与编译 Android系统的下载与编译,Google的官方网站上已经给出了详细的说明,请参照Android的官方网址: htt ...

  6. 在Winform中菜单动态添加“最近使用文件”

    最近在做文件处理系统中,要把最近打开文件显示出来,方便用户使用.网上资料有说,去遍历“C:\Documents and Settings\Administrator\Recent”下的最近文档本.文主 ...

  7. 用户管理 之 在Linux系统中,批量添加用户的操作流程

    一.阅读此文件您需要掌握的基础知识: <Linux 用户(user)和用户组(group)管理概述><用户(user)和用户组(group)配置文件详解><Linux 用 ...

  8. Linux——解决RedHat6/CentOS6系统中“弹出界面eth0:设备似乎不存在”的问题

    刚刚在自己的CentOS6系统中执行service network restart时,竟然提示: 弹出界面 eth0: 设备 似乎不存在, 初始化操作将被延迟.   [失败] 这事可真神奇.于是手动编 ...

  9. Android应用中菜单(Menu)的位置显示问题

    http://blog.csdn.net/songjinshi/article/details/17381245 注意:为了适配4.0菜单能够横向显示,建议在activity中添加android:th ...

随机推荐

  1. Create a simple REST web service with Python--转载

    今日尝试用python建立一个restful服务. 原文地址:http://www.dreamsyssoft.com/python-scripting-tutorial/create-simple-r ...

  2. Java向上转型注意事项

    继承.接口:Java子类中如果含有父类中不包含的变量与方法,子类对象向上转型时就是丢失这些变量和方法. interface SuperClass{ int i = 2; void f() ; } cl ...

  3. (转)How to renew your Apple Push Notification Push SSL Certificate

    转自:https://blog.serverdensity.com/how-to-renew-your-apple-push-notification-push-ssl-certificate/ It ...

  4. LSI SAS 2308配置操作

    介绍LSISAS2308的配置操作 3.1 登录CU界面 介绍登录LSISAS2308的CU配置界面的方法. 3.2 创建RAID 介绍在LSISAS2308扣卡上创建RAID的操作方法. 3.3 配 ...

  5. C#(Net)软件开发常用工具汇总,提高你的开发效率

    C#(Net)软件开发常用工具汇总,提高你的开发效率 写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用技术文章. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是 ...

  6. H3 BPM 笔记

    先通过流程设计器设计流程 注意  审批:1个人 会签: 多人用 同意时: 若为有一个同意就通过 则 审批选项卡 的同意出口 设为1 如果需要所有人同意才通过 则  审批选项卡 的同意出口 设为100% ...

  7. Polyline对象 - (及其他对象的关系)

    Polyline对象是由一个或多个相连或者不相连的path对象的有序集合,通常用来代表线状地物如道路,河流,管线等等.

  8. AngularJs练习Demo17 ngRoute

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  9. 启动外部exe程序

    Process myProcess = new Process();myProcess.StartInfo.FileName = pathName;myProcess.Start();其中的pathN ...

  10. 关于jdbc Oracle数据库连接的URL错误

    今天写了个java类连接oracle,抛出了这个问题 java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@127 ...