Android系列之UI组件----Menu菜单

Android系列之UI组件----Menu菜单

 

【声明】html

欢迎转载,但请保留文章原始出处→_→java

生命壹号:http://www.cnblogs.com/smyhvae/android

文章来源:http://www.cnblogs.com/smyhvae/p/4133292.html编程

 

【正文】app

从官方文档了解到,从Android3.0(API level 11)开始,Android设备再也不要求提供一个专门的菜单按钮,转而推荐使用ActionBar。因此如今市面上不少新设备使用三个虚拟按键,并再也不额外提供菜单按钮。ide

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

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

【在XML中定义一个菜单】布局

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

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

  • <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资源变成一个可编程的对象。

 

1、Options menu选项菜单:

OptionMenu,选项菜单,单击手机上的菜单键(MENU)出现,必须设备具备菜单按钮才能够触发。由于屏幕的限制,最多只能展现六个菜单项,若是定义的菜单项超出了六个,其余的菜单项将被隐藏,第六个菜单将会显示“更多”,点击展开更多的菜单。虽然说在Android3.0以后再也不推荐使用选项菜单,可是若是使用了,在Android3.0以后的设备上,选项菜单项将被默认转移到ActionBar中,这个能够经过android:showAsAction属性控制。

建立选项菜单的核心步骤:

(1)重写Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用

(2)调用Menu 的add( )方法添加菜单项(MenuItem),同时能够调用MenuItem的setIcon()方法为菜单项设置图标(注:Android 3.0以后,即便添加了图标也不会显示)

(3)重写Activity的OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件

来看一下具体的代码实现:

新建Android工程MenuTest:

【方式一】经过配置文件添加Menu选项

(1)在res/menu/main.xml中定义菜单项。main.xml的代码以下:

复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> </menu>
复制代码

注:第9行和第15行的字符串引用,须要提早在strings.xml文件中设置好。

(2)MainActivity.java:

复制代码
 1 package com.example.menutest;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.Menu;  6 import android.view.MenuItem;  7 import android.widget.Toast;  8  9 10 public class MainActivity extends Activity { 11 12  @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15  setContentView(R.layout.activity_main); 16  } 17 18 19 //重写onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用 20  @Override 21 public boolean onCreateOptionsMenu(Menu menu) { 22 // Inflate the menu; this adds items to the action bar if it is present. 23 //填充选项菜单(读取XML文件、解析、加载到Menu组件上) 24  getMenuInflater().inflate(R.menu.main, menu); 25 return true; 26  } 27 28 //重写OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件(根据id来区分是哪一个item) 29  @Override 30 public boolean onOptionsItemSelected(MenuItem item) { 31 // Handle action bar item clicks here. The action bar will 32 // automatically handle clicks on the Home/Up button, so long 33 // as you specify a parent activity in AndroidManifest.xml. 34 switch (item.getItemId()) { 35 case R.id.start: 36 Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show(); 37 break; 38 case R.id.over: 39 Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show(); 40 break; 41 42 default: 43 break; 44  } 45 return super.onOptionsItemSelected(item); 46  } 47 }
复制代码

核心代码是第24行:引用布局文件menu.xml,而后在30行的方法中添加MenuItem的点击事件。

运行程序,效果以下:

若是想让MenuItem变成ActionBar的形式,能够修改res/menu/main.xml中的android:showAsAction属性,它的属性值一共有下面几种:

其中,ifRoom表示:若是有空间,就显示出来。withText表示:只显示文本(若是配了图标的话)。若是将属性设置为always,效果以下:

若是须要添加子菜单,能够修改menu.xml文件为以下所示:

复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> <!-- 子菜单 --> <item android:id="@+id/setting" android:title="setting"> <menu> <item android:id="@+id/setting1" android:orderInCategory="300" android:showAsAction="never" android:title="声音設置"/> <item android:id="@+id/setting2" android:orderInCategory="400" android:showAsAction="never" android:title="背景設置"/> </menu> </item> </menu>
复制代码

因而,子菜单的点击事件为:

复制代码
    public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. switch (item.getItemId()) { case R.id.start: Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show(); break; case R.id.over: Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show(); break; case R.id.setting1: Toast.makeText(this, "声音設置", Toast.LENGTH_SHORT).show(); break; case R.id.setting2: Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show(); break; default: break; } return super.onOptionsItemSelected(item); }
复制代码

运行效果以下:

 

【方式二】经过Java代码添加Menu选项:

固然了,上方的方式一是经过xml文件来添加Menu选项的,下面咱们经过Java代码来添加Menu选项(此时已经不须要menu.xml文件了)。修改MainActivity.java,代码以下: 

MainActivity.java:

复制代码
 1 package com.example.menutest;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.Menu;  6 import android.view.MenuItem;  7 import android.view.SubMenu;  8 import android.widget.Toast;  9 10 11 public class MainActivity extends Activity { 12 13 14 private static final int START_ITEM = Menu.FIRST; //Menu.FIRST的值就是1 15 private static final int OVER_ITEM = Menu.FIRST+1; 16 private static final int SET_ITEM1 = Menu.FIRST+2; 17 private static final int SET_ITEM2 = Menu.FIRST+3; 18 19 20  @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23  setContentView(R.layout.activity_main); 24  } 25 26 27 //重写onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用 28  @Override 29 public boolean onCreateOptionsMenu(Menu menu) { 30 // Inflate the menu; this adds items to the action bar if it is present. 31 //填充选项菜单(读取XML文件、解析、加载到Menu组件上) 32 // getMenuInflater().inflate(R.menu.main, menu); 33 34 //经过代码的方式来添加Menu 35 //添加菜单项(组ID,菜单项ID,排序,标题) 36 menu.add(0, START_ITEM, 100, "Start"); 37 menu.add(0, OVER_ITEM, 200, "Over"); 38 //添加子菜单 39 SubMenu sub1 = menu.addSubMenu("setting"); 40 sub1.add(1, SET_ITEM1, 300, "声音设置"); 41 sub1.add(1, SET_ITEM2, 400, "背景设置"); 42 43 return true; 44  } 45 46 //重写OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件(根据id来区分是哪一个item) 47  @Override 48 public boolean onOptionsItemSelected(MenuItem item) { 49 // Handle action bar item clicks here. The action bar will 50 // automatically handle clicks on the Home/Up button, so long 51 // as you specify a parent activity in AndroidManifest.xml. 52 switch (item.getItemId()) { 53 case START_ITEM: 54 Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show(); 55 break; 56 case OVER_ITEM: 57 Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show(); 58 break; 59 60 case SET_ITEM1: 61 Toast.makeText(this, "声音設置", Toast.LENGTH_SHORT).show(); 62 break; 63 64 case SET_ITEM2: 65 Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show(); 66 break; 67 68 default: 69 break; 70  } 71 return super.onOptionsItemSelected(item); 72  } 73 }
复制代码

注意第35行对各个参数的解释。

运行程序,效果和上方gif图的效果是同样的。

总结:推荐用方式1来作。

 

2、Context menu:上下文菜单

顾名思义 与上下文(环境)有关。操做时须要长时间按住某个item不放,就会弹出Context menu。效果以下:

建立上下文菜单的核心步骤:

(1)覆盖Activity的onCreateContextMenu(Menu menu)方法,调用Menu的add()方法添加菜单项(MenuItem)

(2)覆盖Activity的onContextItemSelected(MenuItem iitem)来响应事件

(3)调用registerForContextMenu()方法来为视图注册上下文菜单。

如今经过代码来实现。

从新建一个Android工程MenuTest02,步骤以下:

咱们如今activity_main.xml中添加一个按钮button1,代码就不写了。而后继续:

(1)在res/menu/main.xml中定义菜单项。main.xml的代码以下:

复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest02.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> </menu>
复制代码

(2)MainActivity.java:

复制代码
 1 package com.example.menutest02;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.ContextMenu;  6 import android.view.MenuItem;  7 import android.view.View;  8 import android.view.ContextMenu.ContextMenuInfo;  9 import android.widget.Button; 10 import android.widget.Toast; 11 12 13 public class MainActivity extends Activity { 14 15 private Button button1; 16  @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19  setContentView(R.layout.activity_main); 20 button1 = (Button)findViewById(R.id.button1); 21 //为按钮绑定上下文菜单(注意不是绑定监听器) 22  registerForContextMenu(button1); 23  } 24 25 //建立上下文菜单 26  @Override 27 public void onCreateContextMenu(ContextMenu menu, View v, 28  ContextMenuInfo menuInfo) { 29 super.onCreateContextMenu(menu, v, menuInfo); 30 31  getMenuInflater().inflate(R.menu.main, menu); 32  } 33 34 //上下文菜单的触发事件 35  @Override 36 public boolean onContextItemSelected(MenuItem item) { 37 switch (item.getItemId()) { 38 case R.id.start: 39 Toast.makeText(this, "开始···", Toast.LENGTH_SHORT).show(); 40 break; 41 42 case R.id.over: 43 Toast.makeText(this, "结束···", Toast.LENGTH_SHORT).show(); 44 break; 45 46 default: 47 break; 48  } 49 50 return super.onContextItemSelected(item); 51  } 52 53 }
复制代码

核心代码是第22行:为按钮button1绑定上下文菜单。注意不是绑定监听器哦,不要一看到按钮就绑定监听器哈。

注:一个界面中只能有一个上下文菜单。

运行程序,长按button,效果以下:

注:若是是在java代码中添加Menu,用参数menu来天添加就好了。

 

3、Popup menu:弹出式菜单

 PopupMenu,弹出菜单,一个模态形式展现的弹出风格的菜单,绑在在某个View上,通常出如今被绑定的View的下方(若是下方有空间)。

注意:弹出菜单是在API 11和更高版本上才有效的。

核心步骤:

(1)经过PopupMenu的构造函数实例化一个PopupMenu对象,须要传递一个当前上下文对象以及绑定的View。

(2)调用PopupMenu.setOnMenuItemClickListener()设置一个PopupMenu选项的选中事件。

(3)使用MenuInflater.inflate()方法加载一个XML文件到PopupMenu.getMenu()中。

(4)在须要的时候调用PopupMenu.show()方法显示。

如今经过代码来实现。从新新建一个工程文件MenuTest03。步骤以下:

先在布局文件activity_main.xml中加一个按钮,代码略。

(1)在res/menu/main.xml中定义菜单项。main.xml的代码以下:

复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest03.MainActivity" > <item android:id="@+id/copy" android:orderInCategory="100" android:title="复制"/> <item android:id="@+id/delete" android:orderInCategory="100" android:title="粘贴"/> </menu>
复制代码

(2)MainActivity.java:

复制代码
 1 package com.example.menutest03;  2  3 import android.app.Activity;import android.os.Bundle;  4 import android.view.MenuInflater;  5 import android.view.MenuItem;  6 import android.view.View;  7 import android.view.View.OnClickListener;  8 import android.widget.Button;  9 import android.widget.PopupMenu; 10 import android.widget.PopupMenu.OnMenuItemClickListener; 11 import android.widget.Toast; 12 13 14 public class MainActivity extends Activity implements OnClickListener,OnMenuItemClickListener{ 15 16 17 private Button button1; 18  @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21  setContentView(R.layout.activity_main); 22 button1 = (Button)findViewById(R.id.button1); 23 button1.setOnClickListener(this); 24  } 25 26 //点击按钮后,加载弹出式菜单 27  @Override 28 public void onClick(View v) { 29 //建立弹出式菜单对象(最低版本11) 30 PopupMenu popup = new PopupMenu(this, v);//第二个参数是绑定的那个view 31 //获取菜单填充器 32 MenuInflater inflater = popup.getMenuInflater(); 33 //填充菜单 34  inflater.inflate(R.menu.main, popup.getMenu()); 35 //绑定菜单项的点击事件 36 popup.setOnMenuItemClickListener(this); 37 popup.show(); //这一行代码不要忘记了 38 39  } 40 41 //弹出式菜单的单击事件处理 42  @Override 43 public boolean onMenuItemClick(MenuItem item) { 44 // TODO Auto-generated method stub 45 switch (item.getItemId()) { 46 case R.id.copy: 47 Toast.makeText(this, "复制···", Toast.LENGTH_SHORT).show(); 48 break; 49 50 case R.id.delete: 51 Toast.makeText(this, "删除···", Toast.LENGTH_SHORT).show(); 52 break; 53 default: 54 break; 55  } 56 return false; 57  } 58 59 }
复制代码

注意14行代码绑定了两个监听器:OnClickListener和OnMenuItemClickListener。 在绑定OnMenuItemClickListener监听器时,选的是下面这个:

 

若是是在API 14及以上版本,32行34行能够合并为:popup.inflate(R.menu.main, popup.getMenu());

注意第37行代码不要忘记show。

运行程序,单击button,效果以下:

最后,附上整个文章的代码:

【工程文件】

连接:http://pan.baidu.com/s/1eQ6EnUq 

密码:438o

相关文章
相关标签/搜索