AndroidStudio5.7 menu

1. Learning objectives

  1. Know three menu usage scenarios
  2. Able to use three menus correctly

2. Summary

Menus occupy an important position in Android applications. Native Android provides three types of menus: options menu (OptionsMenu), context menu (ContextMenu) and submenu (SubMenu). Interested students can play with the Navigation Drawer, which is similar to a sliding menu.
Insert image description here

3. Explanation

(1) Menu overview

  • Menus occupy an important position in Android applications. Native Android provides three types of menus: options menu (OptionsMenu), context menu (ContextMenu) and submenu (SubMenu). In actual Android projects, SlidingMenu (sliding menu) is often used, but it requires us to learn how to use third-party open source libraries.

1. Options menu

  • Create options menu
1 @Override                                               
2 public boolean onCreateOptionsMenu(Menu menu) {
    
             
3     return super.onCreateOptionsMenu(menu);      

2. Text menu

  • Register a context menu for a control
1 registerForContextMenu(tvWelcome);

3. Submenu

  • Add submenu
1 menu.addSubMenu(1, 1, 1, "设置红色");

(2) Case demonstration of option menu

1. Create an Android application

  • Create an Android application based on the Empty Activity template - OptionsMenuDemo
    Insert image description here
  • Click the [Finish] button
    Insert image description here

2. Prepare picture materials

  • Copy the background image to the drawable directory
    Insert image description here

3. String resource file

  • String resource file - strings.xml
    Insert image description here
<resources>
    <string name="app_name">选项菜单演示</string>
    <string name="popup_options_menu">弹出选项菜单</string>
</resources>

4. Main layout resource file

  • Main layout resource file - activity_main.xml
    Insert image description here
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:context=".MainActivity">

</LinearLayout>

5. Main interface class implementation function

  • Main interface class - MainActivity
    Insert image description here
  • Declare menu identification constants
    Insert image description here
  • Create options menu
    Insert image description here
  • Create menu item selection event method
    Insert image description here
  • View full code
package net.fzy.optionsmenudemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.widget.Toolbar;

public class MainActivity extends AppCompatActivity {
    
    

    private static final int NEW_FILE_MENU = 1; // 新建文件菜单标识
    private static final int OPEN_FILE_MENU = 2; // 打开文件菜单标识
    private static final int SAVE_FILE_MENU = 3; // 保存文件菜单标识
    private static final int EXIT_APP_MENU = 4;  // 退出应用菜单标识

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

    /**
     * 创建选项菜单
     *
     * @param menu
     * @return 是否成功
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
    
        // 添加四个菜单项(组标识、菜单项标识、菜单项序号、菜单项标题)
        menu.add(1, NEW_FILE_MENU, 1, "新建文件");
        menu.add(1, OPEN_FILE_MENU, 2, "打开文件");
        menu.add(1, SAVE_FILE_MENU, 3, "保存文件");
        menu.add(1, EXIT_APP_MENU, 4, "退出应用");
        return true;
    }

    /**
     * 菜单项选择事件处理方法
     *
     * @param item
     * @return 是否成功
     */
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
    
        // 根据菜单项标识判断用户单击了哪个菜单项
        switch (item.getItemId()) {
    
    
            case NEW_FILE_MENU: // 新建文件菜单项
                Toast.makeText(this, "你单击了【新建文件】菜单项~", Toast.LENGTH_SHORT).show();
                break;
            case OPEN_FILE_MENU: // 打开文件菜单项
                Toast.makeText(this, "你单击了【打开文件】菜单项~", Toast.LENGTH_SHORT).show();
                break;
            case SAVE_FILE_MENU: // 保存文件菜单项
                Toast.makeText(this, "你单击了【保存文件】菜单项~", Toast.LENGTH_SHORT).show();
                break;
            case EXIT_APP_MENU: // 退出应用菜单项
                finish(); // 关闭当前窗口
                break;
        }
        return true;
    }
}

6. Start the application and check the effect

  • Click the three-dot button on the right side of the activity bar to pop up the options menu
    Insert image description here

(3) Context menu case demonstration

1. Create an Android application

  • Create an Android application based on the Empty Activity template - ContextMenuDemo
    Insert image description here
  • Click the [Finish] button
    Insert image description here

2. Prepare picture materials

  • Copy the picture material to the drawable directory
    Insert image description here

3. String resource file

  • String resource file - strings.xml
    Insert image description here
<resources>
    <string name="app_name">上下文菜单演示</string>
    <string name="file">文件</string>
    <string name="edit">编辑</string>
</resources>

4. Main layout resource file

  • Main layout resource file - activity_main.xml
    Insert image description here
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"   
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:background="#eeeeee">

        <TextView
            android:id="@+id/tv_file"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="15dp"
            android:text="@string/file"
            android:textColor="#0000ff"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/edit"
            android:textColor="#0000ff"
            android:textSize="20sp" />
    </LinearLayout>
</LinearLayout>
  • View preview effect
    Insert image description here

5. Main interface class implementation function

  • Main interface class - MainActivity
    Insert image description here
  • Declare variables and constants
    Insert image description here
  • Get the control instance by resource identifier
    Insert image description here
  • Register context menus for two label controls
    Insert image description here
  • Write methods that set the icon available
    Insert image description here
  • Write a method to create a context menu
    Insert image description here
  • Write context menu item selection event handling method
    Insert image description here
  • View full code
package net.fzy.contextmenudemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {
    
    

    private TextView tvFile; // 文件标签
    private TextView tvEdit; // 编辑标签

    private static final int NEW_FILE_MENU_ITEM = 1; // 新建文件菜单项标识
    private static final int OPEN_FILE_MENU_ITEM = 2; // 打开文件菜单项标识
    private static final int SAVE_FILE_MENU_ITEM = 3; // 保存文件菜单项标识
    private static final int EXIT_APP_MENU_ITEM = 4; // 退出应用菜单项标识

    private static final int CUT_MENU_ITEM = 5; // 剪切菜单项标识
    private static final int COPY_MENU_ITEM = 6; // 复制菜单项标识
    private static final int PASTE_MENU_ITEM = 7; // 粘贴菜单项标识

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        // 通过资源标识符获取控件实例
        tvFile = findViewById(R.id.tv_file);
        tvEdit = findViewById(R.id.tv_edit);

        // 给两个标签控件注册上下文菜单
        registerForContextMenu(tvFile);
        registerForContextMenu(tvEdit);
    }

    /**
     * 设置图标可用的方法
     *
     * @param menu
     * @param enabled
     */
    private void setIconEnabled(Menu menu, boolean enabled) {
    
    
        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, enabled);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 创建上下文菜单
     *
     * @param menu 上下文菜单
     * @param v 注册上下文菜单的控件
     * @param menuInfo 菜单信息
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    
    
        super.onCreateContextMenu(menu, v, menuInfo);
        // 设置菜单图标可用
        setIconEnabled(menu, true);
        // 针对不同控件创建不同的上下菜单
        switch (v.getId()) {
    
    
            case R.id.tv_file: // 文件标签
                // 设置菜单图标
                menu.setHeaderIcon(R.drawable.file);
                // 设置菜单标题
                menu.setHeaderTitle(R.string.file);
                // 添加菜单项(组标识、菜单项标识、菜单项序号、菜单项标题)
                menu.add(1, NEW_FILE_MENU_ITEM, 1, "新建文件").setIcon(R.drawable.new_file);
                menu.add(1, OPEN_FILE_MENU_ITEM, 2, "打开文件").setIcon(R.drawable.open_file);
                menu.add(1, SAVE_FILE_MENU_ITEM, 3, "保存文件").setIcon(R.drawable.save_file);
                menu.add(1, EXIT_APP_MENU_ITEM, 4, "退出应用").setIcon(R.drawable.exit_app);
                break;
            case R.id.tv_edit: // 编辑标签
                // 设置菜单图标
                menu.setHeaderIcon(R.drawable.edit);
                // 设置菜单标题
                menu.setHeaderTitle(R.string.edit);
                // 添加菜单项(组标识、菜单项标识、菜单项序号、菜单项标题)
                menu.add(2, CUT_MENU_ITEM, 1, "剪切").setIcon(R.drawable.cut);
                menu.add(2, COPY_MENU_ITEM, 2, "复制").setIcon(R.drawable.copy);
                menu.add(2, PASTE_MENU_ITEM, 3, "粘贴").setIcon(R.drawable.paste);
                break;
        }
    }

    /**
     * 上下文菜单项选择事件处理方法
     *
     * @param item
     * @return
     */
    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
    
    
        // 根据菜单项标识判断用户选择了哪个菜单项
        switch (item.getItemId()) {
    
    
            case NEW_FILE_MENU_ITEM: // 新建文件菜单项
                Toast.makeText(this, "你单击了【新建文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case OPEN_FILE_MENU_ITEM: // 打开文件菜单项
                Toast.makeText(this, "你单击了【打开文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case SAVE_FILE_MENU_ITEM: // 保存文件菜单项
                Toast.makeText(this, "你单击了【保存文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case EXIT_APP_MENU_ITEM: // 退出应用菜单项
                finish(); // 关闭当前窗口,退出应用
                break;
            case CUT_MENU_ITEM: // 剪切菜单项
                Toast.makeText(this, "你单击了【剪切】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case COPY_MENU_ITEM: // 复制菜单项
                Toast.makeText(this, "你单击了【复制】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case PASTE_MENU_ITEM: // 粘贴菜单项
                Toast.makeText(this, "你单击了【粘贴】菜单项!", Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }
}

6. Start the application and check the effect

  • Long press the [File] or [Edit] label, and the corresponding context menu will pop up.
    Insert image description here

(4) Submenu case demonstration

  • A submenu can be either a submenu of an options menu or a submenu of a context menu.

1. Create an Android application

  • Create an Android application based on the Empty Activity template - SubMenuDemo
    Insert image description here
  • Click the [Finish] button
    Insert image description here

2. Prepare picture materials

  • Copy the picture material to the drawable directory
    Insert image description here

3. String resource file

  • String resource file - strings.xml
    Insert image description here
<resources>
    <string name="app_name">子菜单演示</string>
</resources>

4. Main layout resource file

  • Main layout resource file - activity_main.xml
    Insert image description here
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical"
    tools:context=".MainActivity">

</LinearLayout>

5. Main interface class implementation function

  • Main interface class - MainActivity
    Insert image description here
  • Define constants and variables
    Insert image description here
  • Get the control instance by resource identifier
    Insert image description here
  • Create an options menu and its submenus
    Insert image description here
  • Write menu item event handling methods
    Insert image description here
  • View full source code
package net.fzy.submenudemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
    
    

    private LinearLayout root; // 线性根布局

    private static final int SET_BACKGROUND_COLOR_MENU = 1;  // 设置背景颜色菜单
    private static final int RED_MENU_ITEM = 11;  // 红色背景菜单项
    private static final int GREEN_MENU_ITEM = 12; // 绿色背景菜单项
    private static final int BLUE_MENU_ITEM = 13; // 蓝色背景菜单项

    private static final int SET_BACKGROUND_IMAGE_MENU = 2; // 设置背景图片菜单
    private static final int SCENERY_MENU_ITEM = 21; // 风景背景菜单项
    private static final int BUILDING_MENU_ITEM = 22; // 建筑背景菜单项
    private static final int PERSON_MENU_ITEM = 23; // 人物背景菜单项

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        // 通过资源标识符获取控件实例
        root = findViewById(R.id.root);
    }

    /**
     * 创建选项菜单及其子菜单
     *
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
    
        // 创建设置背景颜色子菜单
        SubMenu setBackgroundColorSubMenu = menu.addSubMenu(1, SET_BACKGROUND_COLOR_MENU, 1, "设置背景颜色");
        // 给子菜单添加菜单项
        setBackgroundColorSubMenu.add(1, RED_MENU_ITEM, 1, "红色");
        setBackgroundColorSubMenu.add(1, GREEN_MENU_ITEM, 2, "绿色");
        setBackgroundColorSubMenu.add(1, BLUE_MENU_ITEM, 3, "蓝色");

        // 创建设置背景图片子菜单
        SubMenu setBackgroundImageSubMenu = menu.addSubMenu(2, SET_BACKGROUND_COLOR_MENU, 2, "设置背景图片");
        // 给子菜单添加菜单项
        setBackgroundImageSubMenu.add(2, SCENERY_MENU_ITEM, 1, "风景");
        setBackgroundImageSubMenu.add(2, BUILDING_MENU_ITEM, 2, "建筑");
        setBackgroundImageSubMenu.add(2, PERSON_MENU_ITEM, 3, "人物");

        return true;
    }

    /**
     * 菜单项选择事件处理方法
     *
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
    
        // 根据用户选择的菜单项执行不同的操作
        switch (item.getItemId()) {
    
    
            case RED_MENU_ITEM: // 设置红色背景
                root.setBackgroundColor(Color.RED);
                break;
            case GREEN_MENU_ITEM: // 设置绿色背景
                root.setBackgroundColor(Color.GREEN);
                break;
            case BLUE_MENU_ITEM: // 设置蓝色背景
                root.setBackgroundColor(Color.BLUE);
                break;
            case SCENERY_MENU_ITEM: // 设置风景背景
                root.setBackgroundResource(R.drawable.scenery);
                break;
            case BUILDING_MENU_ITEM: // 设置建筑背景
                root.setBackgroundResource(R.drawable.building);
                break;
            case PERSON_MENU_ITEM: // 设置人物背景
                root.setBackgroundResource(R.drawable.person);
                break;
        }
        return true;
    }
}

6. Start the application and check the effect

  • Test two submenus: set background color and set background image
    Insert image description here

(5) Generate menu using menu configuration file

1. Create an Android application

  • Create an installation application based on the Empty Activity template - XMLMenu
    Insert image description here
  • Click the [Finish] button
    Insert image description here

2. Prepare picture materials

  • Copy the picture material to the drawable directory
    Insert image description here

3. String resource file

  • String resource file - strings.xml
    Insert image description here
<resources>
    <string name="app_name">利用XML配置生成菜单</string>
    <string name="file_menu">文件</string>
    <string name="new_file">新建文件</string>
    <string name="open_file">打开文件</string>
    <string name="save_file">保存文件</string>
    <string name="exit_app">退出应用</string>
    <string name="edit_menu">编辑</string>
    <string name="cut">剪切</string>
    <string name="copy">复制</string>
    <string name="paste">粘贴</string>
</resources>

4. Main layout resource file

  • Main layout resource file - activity_main.xml
    Insert image description here
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:context=".MainActivity">

</LinearLayout>

5. Create menu configuration file

  • Create the menu directory in the res directory and create the menu configuration file - main.xml in it
    Insert image description here
<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"
    tools:context="net.hw.xmlmenu.MainActivity">

    <item
        android:id="@+id/file_menu"
        android:title="@string/file_menu"
        app:showAsAction="collapseActionView">
        <menu>
            <item
                android:id="@+id/new_file_menu_item"
                android:icon="@drawable/new_file"
                android:title="@string/new_file"
                app:showAsAction="ifRoom|withText" />
            <item
                android:id="@+id/open_file_menu_item"
                android:icon="@drawable/open_file"
                android:title="@string/open_file"
                app:showAsAction="ifRoom|withText" />
            <item
                android:id="@+id/save_file_menu_item"
                android:icon="@drawable/save_file"
                android:title="@string/save_file"
                app:showAsAction="ifRoom|withText" />
            <item
                android:id="@+id/exit_app_menu_item"
                android:icon="@drawable/exit_app"
                android:title="@string/exit_app"
                app:showAsAction="ifRoom|withText" />
        </menu>
    </item>
    <item
        android:id="@+id/edit_menu"
        android:title="@string/edit_menu"
        app:showAsAction="collapseActionView">
        <menu>
            <item
                android:id="@+id/cut_menu_item"
                android:icon="@drawable/cut"
                android:title="@string/cut"
                app:showAsAction="ifRoom|withText" />
            <item
                android:id="@+id/copy_menu_item"
                android:icon="@drawable/copy"
                android:title="@string/copy"
                app:showAsAction="ifRoom|withText" />
            <item
                android:id="@+id/paste_menu_item"
                android:icon="@drawable/paste"
                android:title="@string/paste"
                app:showAsAction="ifRoom|withText" />
        </menu>
    </item>
</menu>

6. Main interface class implementation function

  • Main interface class - MainActivity
    Insert image description here
  • Create an options menu, use getMenuInflator() to get the menu filler, and call its inflate() method to generate the options menu from the menu configuration file. The first parameter is the menu configuration file identifier, and the second parameter is the options menu object.
    Insert image description here
  • Write menu item selection event handling method
    Insert image description here
  • View full code
package net.fzy.xmlmenu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);
    }

    /**
     * 利用菜单配置文件生成选项菜单
     *
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
    
        // 利用菜单填充器将菜单配置文件填充成菜单
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /**
     * 选项菜单项选择事件处理方法
     *
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
    
        // 根据菜单项标识判断用户选择了哪个菜单项
        switch (item.getItemId()) {
    
    
            case R.id.new_file_menu_item: // 新建文件菜单项
                Toast.makeText(this, "你单击了【新建文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.open_file_menu_item: // 打开文件菜单项
                Toast.makeText(this, "你单击了【打开文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.save_file_menu_item: // 保存文件菜单项
                Toast.makeText(this, "你单击了【保存文件】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.exit_app_menu_item: // 退出应用菜单项
                finish(); // 关闭当前窗口,退出应用
                break;
            case R.id.cut_menu_item: // 剪切菜单项
                Toast.makeText(this, "你单击了【剪切】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.copy_menu_item: // 复制菜单项
                Toast.makeText(this, "你单击了【复制】菜单项!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.paste_menu_item: // 粘贴菜单项
                Toast.makeText(this, "你单击了【粘贴】菜单项!", Toast.LENGTH_SHORT).show();
                break;
        }
        return true; // 事件传播到此为止
    }
}

7. Start the application and check the effect

  • Test the two option menus generated through the configuration file: the file menu and the edit menu
    Insert image description here

Guess you like

Origin blog.csdn.net/qq_62972842/article/details/128284131