博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android--Menus
阅读量:6820 次
发布时间:2019-06-26

本文共 15443 字,大约阅读时间需要 51 分钟。

前言

  本篇博客讲解一下菜单Menu的使用。菜单在windows应用中使用十分广泛,几乎所有的windows应用都有菜单,Android中也加入了菜单的支持。从官方文档了解到,从Android3.0(API level 11)开始,Android设备不再要求提供一个专门的菜单按钮,转而推荐使用ActionBar。所以现在市面上很多新设备使用三个虚拟按键,并不再额外提供菜单按钮,但是按钮的使用也是有些地方可以借鉴的。

  因为Android版本的发展,对于菜单的支持各个版本有很大的区别,而Android3.0是个分水岭,大概可以分为下面三类:

  • OptionMenu和ActionBar:一些操作的集合,如果开发的平台在Android3.0之上,推荐使用ActionBar,如果开发的平台在Android2.3或之下,还是可以使用OptionMenu的。
  • ContextMenu和ActionMode:ContextMenu是一个浮动的窗口形式展现一个选项列表,ActionMode是一个显示在屏幕顶部的操作栏,允许用户选择多个选项,ActionMode在Android3.0之后才有支持。
  • Pupop Menu:PopupMenu是固定在View上的模态菜单,以弹出的方式显示,在Android3.0之后才有支持。

  

在XML中定义一个菜单

  Android提供了标准的XML格式的资源文件来定义菜单项,并且对所有菜单类型都支持,推荐使用XML资源文件来定义菜单,之后再把它Inflater到Activity或者Fragment中,而不是在Activity中使用代码声明。

  而菜单的XML资源文件,需要创建在/res/menu/目录下,并且包含一下几个元素:

  • <menu>:定义一个Menu,是一个菜单资源文件的根节点,里面可以包含一个或者多个<item>和<group>元素。
  • <item>:创建一个MenuItem,代表了菜单中一个选项。
  • <group>:对菜单项进行分组,可以以组的形式操作菜单项。

  <item>元素除了常规的id、icon、title属性的支持,还有一个重要的属性:android:showAsAction,这个属性是起兼容性的,描述了在Android的高版本中,菜单项何时以何种方式加入到ActionBar中。

  <group>是对菜单进行分组,分组后的菜单显示效果并没有区别,唯一的区别在于可以针对菜单组进行操作,这样对于分类的菜单项,操作起来更方便,提供如下的操作:

  • Menu.setGroupCheckable():菜单组内的菜单是否都可选。
  • Menu.setGroupVisible():是否隐藏菜单组的所有菜单。
  • Menu.setGroupEnabled():菜单组的菜单是否有用。

  如果菜单项需要单选或者多选,可以使用android:checkableBehavior属性设置,它可以对单个<item>或者<group>设置一个组,这个属性接受三个参数:single,单选;all,多选,none,没有Checked的选项,默认。

  当创建好一个XML菜单资源文件之后,可以使用MenuInflater.inflate()方法填充菜单资源,使XML资源变成一个可编程的对象。

 

OptionMenu

  OptionMenu,选项菜单,必须设备具有菜单按钮才可以触发。因为屏幕的限制,最多只能展示六个菜单项,如果定义的菜单项超出了六个,其他的菜单项将被隐藏,第六个菜单将会显示“更多”,点击展开更多的菜单。虽说在Android3.0之后不再推荐使用选项菜单,但是如果使用了,在Android3.0之后的设备上,选项菜单项将被默认转移到ActionBar中,这个可以通过android:showAsAction属性控制。

  使用OptionMenu需要在Activity或者Fragment中重写onCreateOptionsMenu()方法,在这个方法中声明一个选项菜单。菜单的存在是为了提供操作,所以Activity和Fragment中还提供了一个onOptionsItemSelected()方法,用于响应选项菜单中选中的时候的响应。OptionMenu就是操作一个Menu对象和MenuItem对象。

  下面通过两个Demo来展示一段选项菜单的使用,分别使用代码声明菜单和XML资源文件声明菜单的方式说明。

  声明代码: 

1 package com.example.menudemo; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.view.SubMenu; 9 import android.widget.Toast;10 11 public class OptionMenu1Activitty extends Activity {12 13     @Override14     protected void onCreate(Bundle savedInstanceState) {15         // TODO Auto-generated method stub16         super.onCreate(savedInstanceState);17         setContentView(R.layout.activity_optionmenu1);18     }19 20     @Override21     public boolean onCreateOptionsMenu(Menu menu) {22         23         //直接Add菜单选项到Menu中24         menu.add(1000, 100, 0, "System menu"); 25         //获取添加的菜单选项,然后设置其图标26         MenuItem menuItem2=menu.add(1000, 101, 1, "User menu"); 27         menuItem2.setIcon(R.drawable.ic_launcher);28         //获取添加的菜单选项,增加一个Intent,点击后转向IntentActivity29         MenuItem menuItem3=menu.add(1000, 102, 2, "Intent menu"); 30         menuItem3.setIcon(R.drawable.ic_launcher);31         Intent intent=new Intent(OptionMenu1Activitty.this, IntentActivity.class);32         menuItem3.setIntent(intent);        33 34         //添加一个SubMenu,点击后弹出一个子菜单对话框35         SubMenu submenu=menu.addSubMenu(1000, 103, 3, "Sub menus");36         submenu.add(1000, 104, 4, "Sub ment1");37         submenu.add(1000, 105, 4, "Sub ment2");38         submenu.add(1000, 106, 4, "Sub ment3");39         return true;40     }41     42     @Override43     public boolean onOptionsItemSelected(MenuItem item) {44         boolean flag;45         switch (item.getItemId()) {46         case 100:47             Toast.makeText(OptionMenu1Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();48             flag=true;49             break;50         case 101:51             Toast.makeText(OptionMenu1Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();52             flag=true;53             break;54         case 104:55             Toast.makeText(OptionMenu1Activitty.this, "selected Sub menu1", Toast.LENGTH_SHORT).show();56             flag=true;57         default:58             flag=super.onOptionsItemSelected(item);59             break;60         }61         return flag;62     }63     64 }

 

  实现效果,Android2.3:

   使用XML资源文件定义选项菜单,XML资源文件:

1 
2
3 4
8
9
14 15
20 21
22
24
26
27
29
30
31
33
35
37
38
39

 Java代码:

1 package com.example.menudemo; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.widget.TextView; 9 import android.widget.Toast;10 11 public class OptionMenu2Activitty extends Activity {12     private TextView  tv;13     @Override14     protected void onCreate(Bundle savedInstanceState) {15         // TODO Auto-generated method stub16         super.onCreate(savedInstanceState);17         setContentView(R.layout.activity_optionmenu1);18         tv=(TextView)findViewById(R.id.tvOptionMenu1);19         tv.setText("加载XML资源填充Menu");        20     }21     22     @Override23     public boolean onCreateOptionsMenu(Menu menu) {24         // 使用布局文件加载菜单25         getMenuInflater().inflate(R.menu.optionmenu2, menu);26         return super.onCreateOptionsMenu(menu);27     }28     29     @Override30     public boolean onOptionsItemSelected(MenuItem item) {31 32         switch (item.getItemId()) {33         case R.id.item1:34             Toast.makeText(OptionMenu2Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();35             return true;36         case R.id.item2:37             Toast.makeText(OptionMenu2Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();38             return true;39         case R.id.item3:40             Intent intent=new Intent(OptionMenu2Activitty.this, IntentActivity.class);41             startActivity(intent);42             return true;43         case R.id.menu_save:44             Toast.makeText(OptionMenu2Activitty.this, "file save", Toast.LENGTH_SHORT).show();45             return true;46         case R.id.sub_menu1:47             Toast.makeText(OptionMenu2Activitty.this, "Selected sub_menu1", Toast.LENGTH_SHORT).show();48             return true;49         default:50             return super.onOptionsItemSelected(item);51         }52         53         54     }55     56 }

  效果和使用Java代码声明菜单一样,这里就不再展示了。

 

ContextMenu

  ,上下文菜单提供了注册在View组件的菜单操作,它以一个浮动的窗口显示(类似于对话框),当用户长按某被注册了上下文菜单的视图,则触发上下文菜单显示。通常都用于ListView或者GridView等视图集合中。

  使用上下文菜单的步骤:

  1. 使用Activity.registerForContextMenu(View)方法为指定View注册上下文菜单。
  2. 在Activity或者Fragment中重写onCreateContextMenu()方法,当被注册的视图接受到长按事件后,系统调用onCreateContextMenu()方法,在这个方法中声明上下文菜单。
  3. 实现onContextItemSelected()方法,用于响应菜单想的选中。

  示例,菜单XML资源文件代码:

1 
2 3
8
13
18

  Java代码:

1 package com.example.menudemo; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.view.ContextMenu; 9 import android.view.MenuInflater;10 import android.view.MenuItem;11 import android.view.View;12 import android.view.ContextMenu.ContextMenuInfo;13 import android.widget.AdapterView.AdapterContextMenuInfo;14 import android.widget.ArrayAdapter;15 import android.widget.ListView;16 import android.widget.Toast;17 18 public class ContextMenu1 extends Activity {19     private ListView listview;20     private List
dataList;21 @Override22 protected void onCreate(Bundle savedInstanceState) {23 super.onCreate(savedInstanceState);24 setContentView(R.layout.activity_contextmenu1);25 listview=(ListView)findViewById(R.id.listView1);26 dataList=getData();27 ArrayAdapter
adapter=new ArrayAdapter
(ContextMenu1.this,android.R.layout.simple_list_item_1, dataList);28 listview.setAdapter(adapter);29 //为ListView注册上下文菜单30 registerForContextMenu(listview);31 }32 33 @Override34 public void onCreateContextMenu(ContextMenu menu, View v,35 ContextMenuInfo menuInfo) {36 super.onCreateContextMenu(menu, v, menuInfo);37 //填充一个XML菜单文件38 MenuInflater inflater = getMenuInflater();39 inflater.inflate(R.menu.contextmenu, menu);40 }41 42 @Override43 public boolean onContextItemSelected(MenuItem item) {44 //获取上下文菜单绑定的AdapterView的额外信息45 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();46 switch (item.getItemId()) {47 case R.id.context_copy:48 Toast.makeText(ContextMenu1.this, "copy "+dataList.get(info.position), Toast.LENGTH_SHORT).show();49 return true;50 case R.id.context_delete:51 Toast.makeText(ContextMenu1.this, "delete "+dataList.get(info.position), Toast.LENGTH_SHORT).show();52 return true;53 case R.id.context_edit:54 Toast.makeText(ContextMenu1.this, "edit " +dataList.get(info.position), Toast.LENGTH_SHORT).show();55 return true;56 default:57 return super.onContextItemSelected(item);58 } 59 }60 //ListView数据61 public List
getData()62 { 63 List
data=new ArrayList
();64 for(int i=0;i<8;i++)65 {66 data.add("item"+i);67 }68 return data;69 } 70 }

  效果展示,Android4.0:

 

ActionMode

  ,是一个系统实现的用户交互,当用户使用ActionMode后,选择一个选项,一个上下文操作栏会出现在屏幕的顶端,呈现出用户可以对当前选中项目进行的操作选项。进入这种状态可以通过后退按钮或者调用finish()退出。ActionMode为Android3.0之后的支持,所以在开发3.0之后的应用,推荐使用ActionMode,而不是ContextMenu。

  使用ActionMode的步骤:

  1. 实现ActionMode.Callback接口。在它的回调方法中,可以设置操作的上下文操作栏。
  2. 在需要显示上下文操作栏的时候,调用startActionMode(ActionMode.Callback)。

  是ActionMode定义的一个内部接口,这个接口需要实现下面四个方法:

  • boolean onCreateActionMode(ActionMode mode,Menu menu):第一次被创建的时候调用。
  • boolean onPrepareActionMode(ActionMode mode,Menu menu):刷新菜单列表的时候被调用,一般使用false即可。
  • boolean onActionItemClicked(ActionMode mode,MenuItem item):菜单项被选中的时候被调用。
  • void onDestroyActionMode(ActionMode mode):退出或销毁的时候被调用。

  示例:

1 package com.example.menudemo;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.annotation.SuppressLint;  7 import android.app.Activity;  8 import android.os.Bundle;  9 import android.view.ActionMode; 10 import android.view.ActionMode.Callback; 11 import android.view.Menu; 12 import android.view.MenuInflater; 13 import android.view.MenuItem; 14 import android.view.View; 15 import android.widget.AdapterView; 16 import android.widget.AdapterView.AdapterContextMenuInfo; 17 import android.widget.AdapterView.OnItemLongClickListener; 18 import android.widget.ArrayAdapter; 19 import android.widget.ListView; 20 import android.widget.Toast; 21  22 public class ActionModeMenu1 extends Activity { 23     private ListView listview; 24     private List
dataList; 25 private ActionMode mActionMode; 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 // TODO Auto-generated method stub 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_contextmenu1); 31 listview=(ListView)findViewById(R.id.listView1); 32 dataList=getData(); 33 ArrayAdapter
adapter=new ArrayAdapter
(ActionModeMenu1.this,android.R.layout.simple_list_item_1, dataList); 34 listview.setAdapter(adapter); 35 listview.setOnItemLongClickListener(new OnItemLongClickListener() { 36 @SuppressLint("NewApi") 37 @Override 38 public boolean onItemLongClick(AdapterView
parent, View view, 39 int position, long id) { 40 if (mActionMode != null) { 41 return false; 42 } 43 //显示ActionMode 44 mActionMode = startActionMode(mActionModeCallback); 45 //标记选中项的下表 46 mActionMode.setTag(position); 47 //标记ListView为可选状态 48 view.setSelected(true); 49 return true; 50 } 51 }); 52 } 53 public List
getData() 54 { 55 List
data=new ArrayList
(); 56 for(int i=0;i<8;i++) 57 { 58 data.add("item"+i); 59 } 60 return data; 61 } 62 63 private ActionMode.Callback mActionModeCallback=new Callback() { 64 65 @Override 66 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 67 //刷新菜单列表的时候被调用,但是一般无需刷新 68 return false; 69 } 70 71 @Override 72 public void onDestroyActionMode(ActionMode mode) { 73 //销毁ActionMode 74 mActionMode = null; 75 } 76 77 @Override 78 public boolean onCreateActionMode(ActionMode mode, Menu menu) { 79 //创建ActionMode 80 //使用资源文件填充 81 MenuInflater inflater = mode.getMenuInflater(); 82 inflater.inflate(R.menu.contextmenu, menu); 83 return true; 84 } 85 86 @Override 87 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 88 //获取选项中下表 89 int position=(Integer)mode.getTag(); 90 switch (item.getItemId()) { 91 case R.id.context_copy: 92 Toast.makeText(ActionModeMenu1.this, "copy "+dataList.get(position), Toast.LENGTH_SHORT).show(); 93 //finish退出ActionMode模式 94 mode.finish(); 95 return true; 96 case R.id.context_delete: 97 Toast.makeText(ActionModeMenu1.this, "delete "+dataList.get(position), Toast.LENGTH_SHORT).show(); 98 mode.finish(); 99 return true;100 case R.id.context_edit:101 Toast.makeText(ActionModeMenu1.this, "edit " +dataList.get(position), Toast.LENGTH_SHORT).show();102 mode.finish();103 return true;104 default:105 return false;106 }107 }108 };109 110 111 }

 效果展示,Android4.0:

 

 

PopupMenu

  ,弹出菜单,一个模态形式展示的弹出风格的菜单,绑在在某个View上,一般出现在被绑定的View的下方(如果下方有空间)。

  使用PopupMenu的步骤:

  1. 通过PopupMenu的构造函数实例化一个PopupMenu对象,需要传递一个当前上下文对象以及绑定的View。
  2. 调用PopupMenu.setOnMenuItemClickListener()设置一个PopupMenu选项的选中事件。
  3. 使用MenuInflater.inflate()方法加载一个XML文件到PopupMenu.getMenu()中。
  4. 在需要的时候调用PopupMenu.show()方法显示。

  示例:

1     public void showPopup(View v){ 2         PopupMenu popup=new PopupMenu(MainActivity.this, v); 3         popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { 4              5             @Override 6             public boolean onMenuItemClick(MenuItem item) { 7                 switch (item.getItemId()) { 8                 case R.id.context_copy: 9                     Toast.makeText(MainActivity.this, "select copy ", Toast.LENGTH_SHORT).show();10                     return true;11                 case R.id.context_delete:12                     Toast.makeText(MainActivity.this, " select delete ", Toast.LENGTH_SHORT).show();13                     return true;14                 case R.id.context_edit:15                     Toast.makeText(MainActivity.this, " select edit ", Toast.LENGTH_SHORT).show();16                     return true;17                     default :18                     return false;19                 }20             }21         });22         popup.getMenuInflater().inflate(R.menu.contextmenu,popup.getMenu());23         popup.show();24     }

  效果展示,Android4.0:

  

总结

  以上就讲解了Android下Menu的使用。因为上面的所有示例均在一个项目中完成的,所以有些低版本的操作,需要更改AndroidManifest.xml文件中的最低支持版本,改到8即可。在现在的实际开发中,最好还是使用对高版本只是的ActionBar、ActionMode、PopupMenu比较好。

 

 

转载地址:http://muszl.baihongyu.com/

你可能感兴趣的文章
【SFTP】使用Jsch实现Sftp文件下载-支持断点续传和进程监控
查看>>
Python--基础知识
查看>>
MySQL 定时任务
查看>>
jxl(Java Excel API) 使用方法 【1】
查看>>
Mac系统中各个文件夹简单介绍(转)
查看>>
流媒体技术学习笔记之(八)海康、大华IpCamera RTSP地址和格式
查看>>
[React] Test friendly approach
查看>>
MySQL InnoDB 引擎的持久性与性能
查看>>
java------HashMap与HashSet的区别
查看>>
GaugeControl 之 DigitalGauge
查看>>
Mysql之sql语句操作
查看>>
C#中按模板操作Word —— 如何向Word中插入图片
查看>>
Linux设备驱动--块设备(三)之程序设计
查看>>
【前端】:jQuery下
查看>>
安卓解析 json 4种格式 全解析
查看>>
asd
查看>>
北斗有 35 颗卫星,而 GPS 有 24 颗卫星,为什么二者数量不同?
查看>>
java中的类、成员变量、方法的修饰符。
查看>>
.NET Core配置文件加载与DI注入配置数据
查看>>
JAVA_StandardServer await create[8005]怎么办
查看>>