【达内课程】OptionsMenu

介绍

OptionMenu 选项菜单,是通过点击设备上的 Menu 键弹出的菜单

【配置菜单】
加载 OptionMenu 是通过执行 Activity 中的 onCreateOptionMenu()方法来实现的。
1、通过配置 res/menu/ 下的菜单配置文件,可以设置菜单项,每个菜单项中:android:id 属性是其唯一标识,亦用于响应点击菜单项时的匹配;android:orderInCategory属性表示菜单项的排序,由小到大排序,如果数字相同,按照代码先后顺序显示;
android:showAsAction属性可以无视;
android:title属性表示菜单项显示的文字;
android:icon属性可以为菜单项配置小图标
2、可以通过在 onCreateOptionMenu()方法中调用参数 Menu 对象的 add()方法动态的添加菜单项

【响应菜单项的点击】
通过重写 onOptionItemSelected()方法可以实现对菜单项的选择的响应

简单使用

通过xml创建选项菜单

MenuActivity

public class MenuActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_file:
                Toast.makeText(this, "点击了File", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_edit:
                Toast.makeText(this, "点击了Edit", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_view:
                Toast.makeText(this, "点击了View", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

在 res 下新建 menu 文件夹,在其中创建 main.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_file"
        android:orderInCategory="100"
        android:title="File"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_edit"
        android:orderInCategory="100"
        android:title="Edit"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_view"
        android:orderInCategory="100"
        android:title="View"
        app:showAsAction="never" />
</menu>

我们运行到模拟机上,虽然模拟机已经没有了 Menu 键,但可以使用 Ctrl+M 快捷键来实现点击了 Menu 键。Menu 之所以显示在下面是因为 MenuActivity 使用的是 NotitleBar 的主题。
在这里插入图片描述

动态添加菜单

menu.add(groupid,itemid,order,title);

groupid,是分组 id,但是由于安卓中的分组没有明显的效果,这里我们都给 0
itemid是不能冲突的,因为我们一会儿要通过item.getItemId()来获得itemid来进行响应
order是排序
title就是最后显示的文字

栗子:通过代码动态添加菜单

public class MenuActivity extends AppCompatActivity {
    public static final int MENU_ITEM_NAVIGATE = 1;
    public static final int MENU_ITEM_CODE = 2;
    public static final int MENU_ITEM_ANALYZE = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //getMenuInflater().inflate(R.menu.main,menu);
        menu.add(Menu.NONE, MENU_ITEM_NAVIGATE, Menu.NONE, "Navigate");
        menu.add(Menu.NONE, MENU_ITEM_CODE, Menu.NONE, "Code");
        menu.add(Menu.NONE, MENU_ITEM_ANALYZE, Menu.NONE, "Analyze");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_ITEM_NAVIGATE:
                Toast.makeText(this, "点击了Navigate", Toast.LENGTH_SHORT).show();
                break;
            case MENU_ITEM_CODE:
                Toast.makeText(this, "点击了Code", Toast.LENGTH_SHORT).show();
                break;
            case MENU_ITEM_ANALYZE:
                Toast.makeText(this, "点击了Analyze", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

效果和刚才是相同的

配置子菜单

1、将一级菜单项的节点修改为首位标签对应的格式,如<item></item>,并在该节点下添加<menu></menu>子节点,然后在<menu></menu>子节点中再添加若干个下级的<item>节点来配置各菜单项
2、将添加一级菜单的add()方法修改为 addSubMenu()方法,并获取该方法的返回值,即 SubMenu 类型的对象,然后调用 SubMenu 对象的 add()方法添加子菜单

在这里插入图片描述

通过xml添加子菜单

修改menu菜单文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_file"
        android:orderInCategory="100"
        android:title="File"
        app:showAsAction="never">
        <menu>
            <item
                android:id="@+id/action_new"
                android:orderInCategory="100"
                android:title="New"
                app:showAsAction="never" />
            <item
                android:id="@+id/action_open"
                android:orderInCategory="100"
                android:title="Open"
                app:showAsAction="never" />
        </menu>
    </item>
    <item
        android:id="@+id/action_edit"
        android:orderInCategory="100"
        android:title="Edit"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_view"
        android:orderInCategory="100"
        android:title="View"
        app:showAsAction="never" />
</menu>

动态添加子菜单

在这里插入图片描述
通过add添加的菜单是一级菜单,不能拥有子菜单;通过menu.addSubMenu()添加的菜单能拥有子菜单。

public class MenuActivity extends AppCompatActivity {
    public static final int MENU_ITEM_NAVIGATE = 1;
    public static final int MENU_ITEM_CODE = 2;
    public static final int MENU_ITEM_ANALYZE = 3;
    public static final int MENU_ITEM_INSPECT_CODE = 4;
    public static final int MENU_ITEM_CODE_CLEANUP = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //getMenuInflater().inflate(R.menu.main,menu);
        menu.add(Menu.NONE, MENU_ITEM_NAVIGATE, Menu.NONE, "Navigate");
        menu.add(Menu.NONE, MENU_ITEM_CODE, Menu.NONE, "Code");
        SubMenu subMenu = menu.addSubMenu(Menu.NONE, MENU_ITEM_ANALYZE, Menu.NONE, "Analyze");
        subMenu.add(Menu.NONE, MENU_ITEM_INSPECT_CODE, Menu.NONE, "Inspect Code");
        subMenu.add(Menu.NONE, MENU_ITEM_CODE_CLEANUP, Menu.NONE, "Code Cleanup");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_ITEM_NAVIGATE:
                Toast.makeText(this, "点击了Navigate", Toast.LENGTH_SHORT).show();
                break;
            case MENU_ITEM_CODE:
                Toast.makeText(this, "点击了Code", Toast.LENGTH_SHORT).show();
                break;
            case MENU_ITEM_INSPECT_CODE:
                Toast.makeText(this, "点击了Inspect Code", Toast.LENGTH_SHORT).show();
                break;
            case MENU_ITEM_CODE_CLEANUP:
                Toast.makeText(this, "点击了Code Cleanup", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

显示图标

在这里插入图片描述
menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_file"
        android:icon="@drawable/clock"
        android:title="定时" />
    <item
        android:id="@+id/action_view"
        android:icon="@drawable/fingerprint"
        android:title="指纹" />
</menu>

程序中重写以下方法

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (menu != null) {
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
                try {
                    Method m = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (NoSuchMethodException e) {
                } catch (Exception e) {
                }
            }
        }
        return super.onPrepareOptionsMenu(menu);
    }

Fragment中使用OptionsMenu

需要在onCreate()中增加setHasOptionsMenu(true);,否则菜单不显示

public static class DetailsFragment extends Fragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setHasOptionsMenu(true);
        }
}

重写以下方法

  @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_message_option,menu);
    }
    
	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.xx:
            	//点击菜单的操作
                break;
        }
        return super.onOptionsItemSelected(item);
    }

实现右上角更多显示菜单

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_file"
        android:icon="@mipmap/ic_message_settings"
        android:title="更多"
        app:showAsAction="always">
        <menu>
            <item
                android:id="@+id/menu_all_read"
                android:title="全部已读" />

            <item
                android:id="@+id/menu_all_clear"
                android:title="清空消息" />
        </menu>
    </item>
</menu>

OptionMenu弹出位置

OptionMenu 的显示以前是显示在 overflow 的下面,5.0 以后显示的位置直接覆盖了 overflow 图标,我们看到上一个栗子中的菜单就是覆盖效果,那么怎么才能实现以下效果呢?
在这里插入图片描述
解决办法:

  1. values-v21 styles.xml文件中添加
  <style name="OverflowMenuStyle" parent="Widget.AppCompat.PopupMenu.Overflow">
        <!-- Api 21 -->
        <item name="overlapAnchor">false</item>
        <!-- 弹出层背景颜色 -->
        <item name="android:popupBackground">@color/action_bar_title_text_color</item>
        <!-- 设置弹出菜单文字颜色 -->
        <item name="android:textColor">@color/message_text</item>
    </style>
  1. 在使用的主题中添加
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>

参考
ActionBar中OptionMenu弹出菜单的位置和overflow右边距的调整

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值