安卓添加应用栏的菜单键(三个点)

前言
当新建android工程后,发现原来使用的ActionBar的屏幕右上角的三个点不再出现了(如图中3),它是因为什么原因不在出现了呢?如果不是我自己的原因,那怎么才能搞出来。这个问题通过下面的方式已经得到了解决。
这里写图片描述

1. 为什么这个菜单键(三点)会不见了?

大概意思也就是说安卓也在不断地进化中,有些东西可能被慢慢替代掉,从 Android 3.0(API 级别 11)开始,采用 Android 技术的设备不必再提供一个专用“菜单”按钮。可以参考sHasPermanentMenuKey()方法的源码解释:

Report if the device has a permanent menu key available to the user.

As of Android 3.0, devices may not have a permanent menu key available.
Apps should use the action bar to present menu options to users.
However, there are some apps where the action bar is inappropriate
or undesirable. This method may be used to detect if a menu key is present.If not, applications should provide another on-screen affordance to access functionality

2.怎么才能搞出来菜单键的功能呢?

关键点:在onCreate()方法中添加下面的方法:他的作用是通过反射的方式获取sHasPermanentMenuKey()方法,这个方法的作用该方法可用于检测菜单键是否存在,并可强制让其可见。

     try {
            ViewConfiguration config = ViewConfiguration.get(this);//得到一个已经设置好设备的显示密度的对象
            Field menuKeyField = ViewConfiguration.class
                    .getDeclaredField("sHasPermanentMenuKey");//反射获取其中的方法sHasPermanentMenuKey(),他的作用是报告设备的菜单是否对用户可用,如果不可用可强制可视化。
            if (menuKeyField != null) {
                //强制设置参数,让其重绘三个点
                menuKeyField.setAccessible(true);
                menuKeyField.setBoolean(config, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

实现步骤:

1) 在工程中的onCreate()方法中,添加如下关键代码。
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getOverflowMenu();//添加方法
    }

    private void getOverflowMenu() {
        try {
            ViewConfiguration config = ViewConfiguration.get(this);//得到一个已经设置好设备的显示密度的对象
            Field menuKeyField = ViewConfiguration.class
                    .getDeclaredField("sHasPermanentMenuKey");//反射获取其中的方法sHasPermanentMenuKey(),他的作用是报告设备的菜单是否对用户可用,如果不可用可强制可视化。
            if (menuKeyField != null) {
                //强制设置参数,让其重绘三个点
                menuKeyField.setAccessible(true);
                menuKeyField.setBoolean(config, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
2)重写onCreateOptionsMenu方法,在这个方法中用getMenuInflater().inflate(R.menu.main, menu)方法填充指定的main.xml文件,然后有两种方法添加item,其效果不同。
A.用menu.add()方法增加内容item,这个方法就不需要在main.xml文件中添加内容,比较方便。
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // 填充menu的main.xml文件; 给action bar添加条目
        getMenuInflater().inflate(R.menu.main, menu);
        menu.add(0, 0, 1, "备注1");// 相当于在res/menu/main.xml文件中,给menu增加一个新的条目item,这个条目会显示title标签的文字(如备注1)
        menu.add(0, 1, 2, "备注2");//第二个参数代表唯一的item ID. 
        menu.add(0, 2, 3, "备注3");
        menu.add(0, 3, 4, "备注4");
        return true;
    }

效果:可以正常显示弹出的菜单list。
这里写图片描述

B.在res/menu/main.xml文件中添加item和属性,也可以填充自定义的其他xml文件。
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/action_settings01"
        android:icon="@drawable/ic_favorite_black_48dp"
        android:title="@string/action_settings01"
         android:showAsAction="ifRoom"/>

    <!-- 在这里添加item-->
    <item android:id="@+id/action_settings02"
          android:title="@string/action_settings02"<!-- 只能通过属性的方式在res/values/string.xml中添加或修改文字 -->
          android:showAsAction="ifRoom"/>
</menu>

效果:可以显示在ActionBar中的,但在弹出的菜单List中没有这个ID:action_settings02的item。

3.重写onOptionsItemSelected()方法, 在点击三点后,这个方法可以根据ID指定在弹出的菜单中的要显示的item内容。其内容可以指定由menu.add()方法增加的item ID,也可以指定由xml添加的item ID(如R.id.action_settings01)。
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case 0://显示由menu.add()方法增加内容item的ID
            Toast.makeText(getApplicationContext(), "1", 1000).show();
            return true;
        case R.id.action_settings03://显示由xml添加的item的ID
            Toast.makeText(getApplicationContext(), "3", 1000).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
扩展:当三个点显示出来后,可以在他的左侧添加其他的文字或者图标。

1.在res/menu/main.xml中添加下面的item,如果不需要让其显示到菜单栏里,而要它显示在应用栏上,那么就不能在onOptionsItemSelected()方法中使用ID定位item。
2.showAsAction为不同关键属性时,可以根据表格查询item出现的对应状态。当许多item使用ifRoom属性并且空间不足时,剩余的item不会显示出来或者挤进三点菜单中。
这里写图片描述

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
        <!-- id可以在类中使用 -->
        android:id="@+id/action_settings01"
        <!-- 如果同时出现icon图片资源和title标题时,一般会忽略文字title内容,图片会占据文字的位置-->
        android:icon="@drawable/ic_favorite_black_48dp"
        <!-- 只能通过属性的方式在res/values/string.xml中添加或修改文字 -->
        android:title="@string/action_settings01"   
        <!-- showAsAction为关键属性 详见下表 -->
         android:showAsAction="ifRoom"/>

    <item android:id="@+id/action_settings02"
          android:title="@string/action_settings02"
          android:showAsAction="ifRoom"/>

    <item android:id="@+id/action_settings03"
          android:title="@string/action_settings03"
          android:showAsAction="ifRoom"/>
</menu>

详细解释:

<menu>定义 Menu,即菜单项的容器。<menu> 元素必须是该文件的根节点,并且能够包含一个或多个 <item><group> 元素。
<item>创建 MenuItem,此元素表示菜单中的一项,可能包含嵌套的 <menu> 元素,以便创建子菜单。
<group>或者<item> 元素的不可见容器(可选)。它支持您对菜单项进行分类,使其共享活动状态和可见性等属性。 
< Item >的关键属性showAsAction,代表了Iitem以什么样的方式和什么时机出现在APP的活动条里(ActionBar),如下:

这里写图片描述

其他的可以关键字可以参阅:https://developer.android.com/guide/topics/resources/menu-resource.html

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值