学而实习之 不亦乐乎

Android:菜单的使用

2020-09-24 20:12:29

一、简介

菜单是Android应用中非常重要且常见的组成部分,主要可以分为三类:选项菜单、上下文菜单/上下文操作模式以及弹出菜单。它们的主要区别如下:
1.选项菜单是一个应用的主菜单项,用于放置对应用产生全局影响的操作,如搜索/设置。
2.上下文菜单是用户长按某一元素时出现的浮动菜单。它提供的操作将影响所选内容,主要应用于列表中的每一项元素(如长按列表项弹出删除对话框)。上下文操作模式将在屏幕顶部栏(菜单栏)显示影响所选内容的操作选项,并允许用户选择多项,一般用于对列表类型的数据进行批量操作。
3.弹出菜单以垂直列表形式显示一系列操作选项,一般由某一控件触发,弹出菜单将显示在对应控件的上方或下方。它适用于提供与特定内容相关的大量操作。

二、用 XML 创建菜单

1.创建资源文件

在res目录下创建 menu 目录,用来存放 menu 资源文件,且每个item必须创建id。

除了<menu>标签外,还有另外两个标签用于设置菜单项和分组,这两个标签分别是<item>和<group>。

实例
(1)普通菜单

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <item
        android:id="@+id/menu_area"
        android:orderInCategory="100"//数值越大级别越小,可设置来排位置
        android:title="@string/choice_area"//文字
        app:showAsAction="always" />//显示方式
    <item
        android:id="@+id/menu_icon"
        android:icon="@mipmap/icon_down"//当icon和title一起使用时,显示图标
        android:orderInCategory="100"
        android:title="@string/choice_area"
        app:showAsAction="always" />
</menu>

(2)包含多级子菜单的选项菜单

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
 
    <item android:id="@+id/option_sub_file"
        android:title="文件"
        app:showAsAction="ifRoom">
        <menu>
            <item android:id="@+id/file_new"
                android:title="新建"/>
            <item android:id="@+id/file_save"
                android:title="保存"/>
 
            <item android:id="@+id/file_more"
                android:title="更多">
                <menu>
                    <item android:id="@+id/file_more_1"
                        android:title="更多1"/>
                    <item android:id="@+id/file_more_2"
                        android:title="更多2"/>
 
                    <item android:id="@+id/file_more_more"
                        android:title="更多更多">
                        <menu>
                            <item android:id="@+id/file_more_more_1"
                                android:title="更多更多1"/>
                            <item android:id="@+id/file_more_more_2"
                                android:title="更多更多2"/>
                        </menu>
                    </item>
                </menu>
            </item>
        </menu>
    </item>
</menu>

2.标签的含义

(1) <menu> 标签:菜单项的容器。<menu>元素必须是该文件的根节点,并且能够包含一个或多个<item>和<group>元素。

(2) <item> 标签:是菜单项,用于定义MenuItem,可以嵌套<menu>元素,以便创建子菜单。

Id:表示菜单项的资源ID
menuCategory:同种菜单项的种类。该属性可取4个值:container、system、secondary和alternative。通过menuCategroy属性可以控制菜单项的位置。例如将属性设为system,表示该菜单项是系统菜单,应放在其他种类菜单项的后面。
orderInCategor:同种类菜单的排列顺序。该属性需要设置一个整数值。例如menuCategory属性值都为system的3个菜单 项(item1、item2和item3)。将这3个菜单项的orderInCategory属性值设为3、2、1,那么item3会显示在最前面,而 item1会显示在最后面。
title:菜单项标题(菜单项显示的文本)
titleCondensed:菜单项的短标题。当菜单项标题太长时会显示该属性值
icon:菜单项图标资源ID
alphabeticShortcut:菜单项的字母快捷键
numericShortcut:菜单项的数字快捷键
checkable:表示菜单项是否带复选框。该属性可设计为true或false
checked:如果菜单项带复选框(checkable属性为true),该属性表示复选框默认状态是否被选中。可设置的值为true或false
visible:菜单项默认状态是否可视
enable:菜单项默认状态是否被激活
app:showAsAction="" 的含义
    >always 任何情况都在toolbar显示
    >ifRoom 当·toolbar·空间足够时,显示,不足时隐藏
    >never 任何情况 不在toolbar上显示,点击在右上角的"更多"才能看见
    >withText 图文(title+icon)显示
    >collapseActionView 隐藏不直接显示

(3) <group> 标签:是<item>元素的不可见容器(可选)。可以使用它对菜单项进行分组,使一组菜单项共享可用性和可见性等属性。

id:表示菜单组的ID
menuCategory:与<item>标签的同名属性含义相同。只是作用域为菜单组
orderInCategory:与<item>标签的同名属性含义相同。只是作用域为菜单组
checkableBehavior:设置该组所有菜单项上显示的选择组件(CheckBox或Radio Button)。如果将该属性值设为all,显示CheckBox组件;如果设为single,显示Radio Button组件;如果设为none,显示正常的菜单项(不显示任何选择组件)。
visible:表示当前组中所有菜单项是否显示。该属性可设置的值是true或false
enable:表示当前组中所有菜单项是否被激活。该属性可设置的值是true或false

三、加载菜单(menu)

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    //load the file of menu that you created
    getMenuInflater().inflate(R.menu.menu_done, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.menu_area) {
        //TODO do everything what you want
        return true;
    } else {
        return super.onOptionsItemSelected(item);
    }
}

四、在代码中动态创建菜单

实例:通过菜单设置文本字体大小和颜色

1.布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txt"
        android:padding="12dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="用于测试的内容" />
</LinearLayout>

2.代码文件 MainActivity.java

public class MainActivity extends Activity {
    // 定义“字体大小”菜单项的标识
    private static final int FONT_10 = 0x111;
    private static final int FONT_12 = 0x112;
    private static final int FONT_14 = 0x113;
    private static final int FONT_16 = 0x114;
    private static final int FONT_18 = 0x115;
    // 定义“普通菜单项”的标识
    private static final int PLAIN_ITEM = 0x11b;
    // 定义“字体颜色”菜单项的标识
    private static final int FONT_RED = 0x116;
    private static final int FONT_BLUE = 0x117;
    private static final int FONT_GREEN = 0x118;
    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = findViewById(R.id.txt);
    }

    // 当用户单击MENU键时触发该方法
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // -------------向menu中添加“字体大小”的子菜单-------------
        SubMenu fontMenu = menu.addSubMenu("字体大小");
        
        fontMenu.setIcon(R.drawable.font);// 设置菜单的图标        
        fontMenu.setHeaderIcon(R.drawable.font);// 设置菜单头的图标
        // 设置菜单头的标题
        fontMenu.setHeaderTitle("选择字体大小");
        fontMenu.add(0, FONT_10, 0, "10号字体");
        fontMenu.add(0, FONT_12, 0, "12号字体");
        fontMenu.add(0, FONT_14, 0, "14号字体");
        fontMenu.add(0, FONT_16, 0, "16号字体");
        fontMenu.add(0, FONT_18, 0, "18号字体");
        
        menu.add(0, PLAIN_ITEM, 0, "普通菜单项");
        
        SubMenu colorMenu = menu.addSubMenu("字体颜色");
        colorMenu.setIcon(R.drawable.color);
        colorMenu.setHeaderIcon(R.drawable.color);
        colorMenu.setHeaderTitle("选择文字颜色");
        colorMenu.add(0, FONT_RED, 0, "红色");
        colorMenu.add(0, FONT_GREEN, 0, "绿色");
        colorMenu.add(0, FONT_BLUE, 0, "蓝色");
        return super.onCreateOptionsMenu(menu);
    }

    //监听菜单事件
    @Override
    public boolean onOptionsItemSelected(MenuItem mi) {
    
        switch (mi.getItemId()) {
            case FONT_10:
                text.setTextSize(10 * 2);
                break;
            case FONT_12:
                text.setTextSize(12 * 2);
                break;
            case FONT_14:
                text.setTextSize(14 * 2);
                break;
            case FONT_16:
                text.setTextSize(16 * 2);
                break;
            case FONT_18:
                text.setTextSize(18 * 2);
                break;
            case FONT_RED:
                text.setTextColor(Color.RED);
                break;
            case FONT_GREEN:
                text.setTextColor(Color.GREEN);
                break;
            case FONT_BLUE:
                text.setTextColor(Color.BLUE);
                break;
            case PLAIN_ITEM:
                Toast.makeText(MainActivity.this,
                        "您单击了普通菜单项", Toast.LENGTH_SHORT)
                        .show();
                break;
        }
        return true;
    }
}