Article directory
1. Menu Overview
- In this lesson we are going to explain the menu, which occupies a relatively 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.
2. Option menu case demonstration
- The options menu provides global functional options for the entire application.
1. Implementation steps
(1). Create Android application [OptionsMenuDemo]
- Click the [finish] button
(2) Prepare picture materials
(3), String resource file
- String resource file -
string.xml
<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
<?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-
MainActivty
-
Declare menu identification constants
-
Create menu item selection event method
package net.xyx.optionsmenudemo;
import androidx.annotation.Nullable;
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;
public class MainActivity extends AppCompatActivity {
private static final int NEW_FILE_MENU = 1;//新建文件菜单标识
private static final int OPEN_FINE_MENU = 2;//打开文件菜单标识
private static final int SAVE_FINE_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(0,NEW_FILE_MENU,1, "新建文件");
menu.add(0,OPEN_FINE_MENU,1, "打开文件");
menu.add(0,SAVE_FINE_MENU,1, "保存文件");
menu.add(0,EXIT_APP_MENU,1, "退出应用");
return true;
}
/**
* 菜单项选择事件处理方法
*
* @param item
* @return 是否成功
*/
@Override
public boolean onOptionsItemSelected(@Nullable MenuItem item){
//根据菜单项标识判断用户单击了哪一个菜单项
switch (item.getItemId()){
case NEW_FILE_MENU://新建文件菜单项
Toast.makeText(this,"你单击了【新建文件】菜单项~",Toast.LENGTH_SHORT).show();
break;
case OPEN_FINE_MENU://打开文件菜单项
Toast.makeText(this,"你单击了【打开文件】菜单项~",Toast.LENGTH_SHORT).show();
break;
case SAVE_FINE_MENU://保存文件菜单项
Toast.makeText(this,"你单击了【保存文件】菜单项~",Toast.LENGTH_SHORT).show();
break;
case EXIT_APP_MENU://退出应用菜单项
Toast.makeText(this,"你单击了【退出应用】菜单项~",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
3. Context menu case demonstration
- Register different context menus for different controls. Long press the control to pop up the context menu belonging to the control.
1. Implementation steps
(1). Create Android application [ContextMenuDemo]
(2) Prepare picture materials
(3), String resource file strings.xml
<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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
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>
(5), main interface class implementation function
-
Main interface class -
MainActivity
-
Declare variables and constants
-
Get control instance
-
Register context menus for two label controls
-
Edit settings icon available methods and context menu
-
Write context menu item selection event handling method
-
View full code
package net.xyx.contextmenu;
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_TIEM = 5;//剪切菜单项标识
private static final int COPY_MENU_TIEM = 6;//拷贝菜单项标识
private static final int PASTE_MENU_TIEM = 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_TIEM, 1, "剪切").setIcon(R.drawable.cut);
menu.add( 2,COPY_MENU_TIEM, 2, "复制").setIcon(R.drawable.copy);
menu.add( 2,PASTE_MENU_TIEM, 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_TIEM://剪切菜单项
Toast.makeText(this,"你单击了【剪切】菜单项!",Toast.LENGTH_SHORT).show();
break;
case COPY_MENU_TIEM://复制菜单项
Toast.makeText(this,"你单击了【复制】菜单项!",Toast.LENGTH_SHORT).show();
break;
case PASTE_MENU_TIEM://粘贴菜单项
Toast.makeText(this,"你单击了【粘贴】菜单项!",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
2. Check the running results
Menu application
4. Submenu case demonstration
- A submenu can be either a submenu of an options menu or a submenu of a context menu.
1. Implementation steps
(1). Create Android applications
- Create an Android application based on the Empty Activity template -
【SubMenuDemo】
- Click the [finish] button
(2). Add the background image material
- Copy the background image to
drawable
directory
(3), String resource file strings.xml
<resources>
<string name="app_name">子菜单演示</string>
</resources>
(4) Main layout resource file
- Main layout resource file
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:id="@+id/root"
android:background="@drawable/background"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</LinearLayout>
(5), main interface class implementation function
- Main interface class -
MainActivity
- Example
- Get the control instance by resource identifier
- Create an options menu and its submenus
- Write menu item event handling methods
2. Check the effect
1670209146203
5. Generate menu using menu configuration file
- It is very convenient to use menu configuration files to generate menus, which can be used to generate option menus and context menus.
1. Implementation steps
(1). Create Android applications
- Create an Android application based on the Empty Activity template -【
XMLMenu
】
- Click the [finish] button
(2) Copy the picture material to the drawable directory
(3), String resource file
String resource file -string.xml
<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
<?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), single configuration file main.xml
- Create the menu directory in the res directory, and then create the menu configuration file in it
main.xml
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="net.hw.xml_menu.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"
android:title="@string/exit_app"
app:showAsAction="ifRoom|withText" />
</menu>
</item>
<item
android:id="@+id/edit_menu"
android:title="@string/edit_menu"
app:showAsAction="aollapseActionView">
<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>
- View preview effect
(6) Main interface class implementation function
- Main interface class -
MainActivity
- Generate options menu using menu configuration file
- Use getMenuInflator() to obtain the menu inflator, and call its inflate() method to generate an 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.
- Write menu item selection event handling method
2. Check the effect
menu