关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android ActionBar中Overflow Menu(溢出菜单)中的一些问题

    Android ActionBar中Overflow Menu(溢出菜单)中的一些问题

    2015-04-01 00:00:00 出处:codeceo
    分享

    前言

    开始前我们先来关注一下Android Overflow menu的几个相关问题:

    什么是Overflow menu Android 3.0以上默认不显示overflow menu 如何强制在Android 4.4.4以下的手机显示overflow menu 经测试,魅族手机无法强制显示overflow menu,其他手机暂无发现这种问题

    先来两张对比图:

    左边是红米手机的效果,右边是针对魅族Mx4pro做的适配效果。

    什么是overflow menu

    先来解释一下什么是overflow menu,中文叫做“溢出菜单”,顾名思义溢出的菜单,我们有些手机是有实体按键或虚拟按键,其中一个是菜单键,有的可能没有,例如魅族就只有一个back的返回虚拟键。点击菜单键的时候,就会在底部弹出溢出菜单,在Android 3.0之后,也就是API 11之后才可以加入ActionBar控件的,再其右上角会有三个点,那个就是我们说的overflow menu,我们在menu中定义菜单项就可以弹出类似上面红米手机弹出的效果。关于ActionBar有很多用法,该文博客就不展开讲,有兴趣的同学可以到官网进行学习。

    如何在ActionBar强制显示溢出菜单?

    Android 3.0以上的手机默认是不显示溢出菜单的,那如何强制在Android 4.4以下的手机显示溢出菜单呢?可以使用以下方法:

    // 强制actionbar显示overflow菜单
    	// force to show overflow menu in actionbar for android 4.4 below
    	private void getOverflowMenu() {
    		try {
    			ViewConfiguration config = ViewConfiguration.get(this);
    			Field menuKeyField = ViewConfiguration.class
    					.getDeclaredField("sHasPermanentMenuKey");
    			if (menuKeyField != null) {
    				menuKeyField.setAccessible(true);
    				menuKeyField.setBoolean(config, false);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}

    适配类似魅族手机无法显示溢出菜单的解决方案

    上面已经解决了如何在Android 4.4以下的手机强制显示溢出菜单,下面来解决一些奇葩手机无法显示溢出菜单的问题。为什么魅族手机无法显示,了解到的是魅族没有所谓的actionbar,它们称为smartbar,看来是魅族的工程师把官方的actionbar进行了修改。一个字,坑!不过小巫想到了一个解决办法,我们每部手机都有自己的手机品牌,我们可以针对这些奇葩手机进行适配,溢出菜单我们就使用popupwindow来替代。

    获得手机信息

    /**
    	 * 获取IMEI号,IESI号,手机型号
    	 */
    	public static void getInfo(Context context) {
    		TelephonyManager mTm = (TelephonyManager) context
    				.getSystemService(Context.TELEPHONY_SERVICE);
    		String imei = mTm.getDeviceId();
    		String imsi = mTm.getSubscriberId();
    		String mtype = android.os.Build.MODEL; // 手机型号
    		String mtyb = android.os.Build.BRAND;// 手机品牌
    		String numer = mTm.getLine1Number(); // 手机号码,有的可得,有的不可得
    		Log.i("text", "手机IMEI号:" + imei + "手机IESI号:" + imsi + "手机型号:" + mtype
    				+ "手机品牌:" + mtyb + "手机号码" + numer);
    	}

    获取手机品牌

    /**
    	 * 得到手机品牌
    	 * @return
    	 */
    	public static String getPhoneBrand() {
    		return android.os.Build.BOARD;
    	}

    得到手机品牌之后,我们就在创建溢出菜单的时候进行判断:

    1. 假如是魅族手机,则加载自定义菜单
    2. 假如不是,则使用系统的溢出菜单,加载菜单内容

    @Override
    	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		super.onCreateOptionsMenu(menu, inflater);
    		String brand = PhoneUtils.getPhoneBrand();
    		if ("mx4pro".equals(brand)) {
    			inflater.inflate(R.menu.overflow_menu, menu);
    		} else {
    			inflater.inflate(R.menu.main, menu);
    		}
    	}

    溢出菜单文件
    /res/menu/main.xm

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
            <item
                android:id="@+id/menu_hotest"
                android:orderInCategory="100"
                android:showAsAction="never"
                android:title="@string/menu_hotest"/>
            <item
                android:id="@+id/menu_lastest"
                android:orderInCategory="100"
                android:showAsAction="never"
                android:title="@string/menu_lastest"/>
    
    </menu>

    自定义的菜单文件

    /res/menu/overflow_menu.xml

    < xml version="1.0" encoding="utf-8" >
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/menu_overflow"
            android:icon="@drawable/ic_more"
            android:orderInCategory="100"
            android:showAsAction="always"
            android:title="@string/menu_overflow">
        </item>
    
    </menu>

    自定义菜单就直接给它设置一个actionbar的按钮,图标是那三个点

    我们在选中菜单的时候执行我们的业务逻辑

    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		switch (item.getItemId()) {
    		case R.id.menu_overflow:
    			popupOverflowMenu();
    			return true;
    		case R.id.menu_lastest:
    			type = "latest";
    			break;
    		case R.id.menu_hotest:
    			type = "hotest";
    			break;
    		default:
    			break;
    		}
    		return super.onOptionsItemSelected(item);
    	}

    假如是魅族mx4pro手机,就弹出我们的自定义菜单,下面是实现:

    /**
    	 * 弹出自定义溢出菜单
    	 */
    	public void popupOverflowMenu() {
    		// 显示溢出菜单的时候设置背景半透明
    		setWindowAlpha(0.5f); 
    		// 获取状态栏高度
    		Rect frame = new Rect();
    		getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
    		// 状态栏高度 frame.top
    		int xOffset = frame.top + getActivity().getActionBar().getHeight() - 25; // 减去阴影宽度,适配UI
    		int yOffset = Dp2Dx(getActivity(), 8f); // 设置x方向offset为5dp
    		View parentView = getActivity().getLayoutInflater().inflate(R.layout.fragment_portfolio, null);
    		View popView = getActivity().getLayoutInflater().inflate(R.layout.action_overflow_menu, null);
    		// popView即popupWindow布局
    		PopupWindow popupWindow = new PopupWindow(popView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
    		// 必须设计BackgroundDrawable后setOutsideTouchable(true)才会有效。这里在XML中定义背景,所以这里为null
    		popupWindow.setBackgroundDrawable(new ColorDrawable(0000000000));
    		popupWindow.setFocusable(true);
    		popupWindow.setOutsideTouchable(true); // 点击外部关闭
    		popupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
    		// 设置Gravity,让它显示在右上角
    		popupWindow.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP, yOffset, xOffset);
    		popupWindow.setOnDismissListener(new OnDismissListener() {
    
    			@Override
    			public void onDismiss() {
    				// popupWindow消失时,设置为全透明
    				setWindowAlpha(1f);
    			}
    		});
    	}
    
    	/**
    	 * 设置屏幕透明度
    	 * @param alpha
    	 */
    	private void setWindowAlpha(float alpha) {
    		WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes();  
    		lp.alpha = alpha; //0.0-1.0  
    		getActivity().getWindow().setAttributes(lp);
    	}
    
    	public int Dp2Dx(Context context, float dp) {
    		final float scale = context.getResources().getDisplayMetrics().density;
    		return (int) (dp * scale + 0.5f);
    	}

    这里就是通过自定义pupupwindow,指定popupwindow的xml布局,这个自己来定,根据父布局来显示popupwindow的位置,当popupwindow显示的时候,设置屏幕为半透明,监听它的消失事件,消失的时候,设置屏幕为全透明效果。最终实现适配魅族手机,这里是小巫想到的一个解决方案,有更好的方法,可以留言交流一下。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。