几种菜单

来源:互联网 发布:软件license @port lic 编辑:程序博客网 时间:2024/04/29 05:40
1. 为什么会有菜单
       菜单一般是提供一些设置或是软件信息什么的,移动设备的屏幕不像PC那么大,不可能在屏幕搞一些按键来触发一些平时使用不会经常操作的事件,比如设置软件配置,查看软件信息什么的。这些功能可以添加到菜单选项中,既提供了该功能,又不会占用屏幕空间。(纯属扯淡有木有啊!!!因为我实在想不出要以什么开头写这篇总结)
2. 菜单的不同创建方法
2.1 动态创建
       通过重写Activity中的onCreateOptionMenu方法来创建菜单,一般使用menu.add(“选项名”)为添加一个菜单选项,menu.getItem(int itemIndex)则是根据选项的索引获取该菜单选项,并对其进行操作,比如添加点击事件onMenuItemClickListener,用addSubMenu添加子菜单等。
优点:创建方便,不需要建立资源文件。
缺点:对于菜单条目过多或多级菜单操作不方便,按键多添加点击事件不方便。
2.2 通过XML资源文件创建
       可以通过menu文件夹下的menu.xml创建菜单的样式,然后再利用getMenuInflater().inflate(menuRes, menu)将创建的菜单样式inflate到程序中。大体主要分三步:
第一步:建立XML资源文件:menu.xml文件一般的定义方式见如下:

view sourceprint?
01.<?xmlversionxmlversion="1.0"encoding="utf-8"?>
02.<menuxmlns:androidmenuxmlns:android="http://schemas.android.com/apk/res/android">
03.<itemandroid:iditemandroid:id="@+id/file"
04.android:title="@string/file">
05.<!-- "file" submenu 添加子菜单 -->
06.<menu>
07.<!-- 子菜单的选项 -->
08.<itemandroid:iditemandroid:id="@+id/create_new"
09.android:title="@string/create_new"/>
10.<itemandroid:iditemandroid:id="@+id/open"
11.android:title="@string/open"/>
12.</menu>
13.</item>
14.</menu>
第二步:在onCreateOptionMenu回调函数完成XML资源的infate,把菜单资源文件压入到程序中,不同菜单使用不同的回调函数,比如ContextMenu使用onCreateContextMenu


view sourceprint?
1.publicbooleanonCreateOptionsMenu(Menu menu) {
2.// Inflate the menu; this adds items to the action bar if it is present.
3.getMenuInflater().inflate(R.menu.main, menu);
4.returntrue;
5.}

第三步:如果我们需要给菜单添加点击事件,一般我们是通过重写onMenuItemSelected来设置的,不同菜单使用不同的点击回调函数,比如ContextMenu使用onContextItemSelected写法如下:

 

view sourceprint?
01.publicbooleanonMenuItemSelected(intfeatureId, MenuItem item) {
02.switch(item.getItemId()) {
03.caseItem.ID1:
04.//do something
05.break;
06.caseItem.ID2:
07.//do something
08.break;
09.//......
10.}
11.returnsuper.onMenuItemSelected(featureId, item);
12.}
3. 菜单的类型:
   3.1 普通菜单:
       一般的普通菜单,点击菜单键后显示出来的菜单,使用方法如第二点所述,只是设置item标签时把showAsAction值设为never即可。
   3.2 显示在ActionBar的菜单:
       这样的菜单可以直接从屏幕中看到,不需要点击菜单键才会显示,要做到这个只需要把Item的showAsAction从never改成ifRoom(如果有空间则显示)或always(总是显示)。例子如下;


view sourceprint?
01.<menuxmlns:androidmenuxmlns:android="http://schemas.android.com/apk/res/android">
02.<item
03.android:id="@+id/info"
04.android:orderInCategory="100"
05.android:showAsAction="never"
06.android:title="软件信息">
07.<menu>
08.<itemandroid:iditemandroid:id="@+id/authorInfo"
09.android:title="软件开发者信息"/>
10.<itemandroid:iditemandroid:id="@+id/versionInfo"
11.android:title="软件版本信息"/>
12.</menu>
13.</item>
14.<!-- 建立一个在Action的菜单选项 -->
15.<item
16.android:id="@+id/settings"
17.android:orderInCategory="100"
18.android:showAsAction="always"
19.android:icon="@drawable/ic_launcher">
20.<menu>
21.<itemandroid:iditemandroid:id="@+id/sysSetting"
22.android:title="系统设置"/>
23.<itemandroid:iditemandroid:id="@+id/softSetting"
24.android:title="软件设置"/>
25.</menu>
26.</item>
27.</menu>
效果图:
 
   3.3 浮动菜单(属于ContextMenu):
       一般添加到ListView或GridView的菜单,长按菜单的某一项可以出发浮动菜单,定义这种菜单主要步骤如下:
1、建立一个View,常用的为ListView或GridView;
2、建立XML菜单资源文件;
3、在Activity中的onCreateContextMenu函数中使用getMenuInflater().inflate()方法将XML菜单资源文件压入;
4、在onContextItemSelected回调函数中添加菜单选项的点击事件。
5、使用registerForContextMenu(View)为该View注册ContextMenu;
 
源码示例如下:

view sourceprint?
01.privateListView list;
02.@Override
03.protectedvoidonCreate(Bundle savedInstanceState) {
04.super.onCreate(savedInstanceState);
05.setContentView(R.layout.activity_main);
06.String[] listItem = { "1""2""3""4""5"};
07.ArrayAdapter<String> aa = newArrayAdapter<String>(this,
08.android.R.layout.simple_list_item_1, listItem);
09.list = (ListView) findViewById(R.id.list);
10.list.setAdapter(aa);
11.registerForContextMenu(list);  
12.//为list注册上下文菜单,通过onCreateContextMenu把XML菜单资源文件压进来,
13.//通过onContextItemSelectd为每个菜单选项添加长按点击事件。
14.}
15.@Override
16.publicvoidonCreateContextMenu(ContextMenu menu, View v,
17.ContextMenuInfo menuInfo) {
18.super.onCreateContextMenu(menu, v, menuInfo);
19.getMenuInflater().inflate(R.menu.float_menu, menu);
20.}
21.@Override
22.publicbooleanonContextItemSelected(MenuItem item) {
23.switch(item.getItemId()) { //判断长按点击了那个选项,为每个选项添加长按点击事件
24.caseR.id.exit:
25.showToast("exit");
26.break;
27.caseR.id.next:
28.showToast("next");
29.break;
30.caseR.id.back:
31.showToast("back");
32.break;
33.}
34.returnsuper.onContextItemSelected(item);
35.}
36.privatevoidshowToast(String str) {
37.Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
38.}
效果图:
   3.4 ActionMode菜单(也属于ContextMenu):
       显示在ActionBar的菜单,这种菜单是用于定义比较重要或常用的功能,放在ActionBar比较显眼。触发这种菜单跟浮动菜单一样,要长按,浮动菜单直接采用注册方法,而该菜单则需要我们去设置View的长按事件(setOnLongClickListener)。
使用方法:
1、建立XML菜单资源文件;
2、建立一个内部类实现ActionMode.Callback接口,实现该接口的四个函数(onCreateActionMode,onPrepareActionMode,onActionItemClicked,onDestroyActionMode)
3、在onCreateActionMode把XML文件压进来,而且返回true!
4、在onActionItemClicked中添加菜单选项点击事件;
5、建立一个View,以Button为例,添加OnLongClickListener事件,事件内容为startActionMode(实现Callback接口的类);
源代码示例:
(1)XML资源文件:

view sourceprint?
01.<LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
02.xmlns:tools="http://schemas.android.com/tools"
03.android:layout_width="match_parent"
04.android:layout_height="match_parent"
05.android:paddingBottom="@dimen/activity_vertical_margin"
06.android:paddingLeft="@dimen/activity_horizontal_margin"
07.android:paddingRight="@dimen/activity_horizontal_margin"
08.android:paddingTop="@dimen/activity_vertical_margin"
09.android:orientation="vertical"
10.tools:context=".MenuActivity2">
11.<Button
12.android:id="@+id/btn_actionMode"
13.android:layout_width="match_parent"
14.android:layout_height="wrap_content"
15.android:text="打开ActionMode菜单"/>
16.<Button
17.android:id="@+id/btn_popUp"
18.android:layout_width="match_parent"
19.android:layout_height="wrap_content"
20.android:text="打开PopUp菜单"/>
21.</LinearLayout>

(2)实现Callback的Java代码:

 

view sourceprint?
01.privateclasscallback implementsActionMode.Callback {
02.@Override
03.publicbooleanonActionItemClicked(ActionMode mode, MenuItem item) {
04.switch(item.getItemId()) {
05.caseR.id.user_info:
06.Toast.makeText(MenuActivity2.this"You click user_info",
07.Toast.LENGTH_SHORT).show();
08.returntrue;
09.caseR.id.user_setting:
10.Toast.makeText(MenuActivity2.this"You click user_setting",
11.Toast.LENGTH_SHORT).show();
12.returntrue;
13.caseR.id.user_login:
14.Toast.makeText(MenuActivity2.this"You click user_login",
15.Toast.LENGTH_SHORT).show();
16.returntrue;
17.default:
18.returnfalse;
19.}
20.}
21.@Override
22.publicbooleanonCreateActionMode(ActionMode mode, Menu menu) {
23.getMenuInflater().inflate(R.menu.menu_activity2, menu);
24.returntrue;
25.}
26.@Override
27.publicvoidonDestroyActionMode(ActionMode mode) {
28.Log.i("cth""ActionMode is destroyed.");
29.actionMode = null;
30.}
31.@Override
32.publicbooleanonPrepareActionMode(ActionMode mode, Menu menu) {
33.returnfalse;
34.}
35.}
(3)长按事件Java代码:

view sourceprint?
01.btn_actionMode = (Button) findViewById(R.id.btn_actionMode);
02.btn_actionMode.setOnLongClickListener(newOnLongClickListener() { //添加长按事件
03.@Override
04.publicbooleanonLongClick(View v) {
05.if(actionMode != null) {
06.returnfalse;
07.}
08.actionMode = startActionMode(newcallback());  //开启ActionMode菜单
09.v.setSelected(true);        //设置为可选
10.returntrue;
11.}
12.});
效果图(红框即为ActionMode菜单):
   3.5 Popup弹出菜单:
       该类菜单需要和某个View绑定,当点击该View时在该View的上面或下面(视屏幕空间而定)弹出菜单。
使用方法:
1、建立XML菜单资源文件;
2~5步均可在绑定View的点击事件中实现!
2、建立PopupMenu对象,实例化传入上下文context和绑定的View;
3、使用PopupMenu对象的getMenuInflater().inflate()把XML菜单文件压进来,
4、使用PopupMenu对象自身的setOnMenuItemClickListener设置点击事件;
5、使用PopupMenu对象自身的show显示弹出菜单。
 
源代码示例:
(1)在View的点击事件中设置2~5步内容:

view sourceprint?
01.btn_popUp = (Button) findViewById(R.id.btn_popUp);
02.btn_popUp.setOnClickListener(newOnClickListener() {
03.@TargetApi(Build.VERSION_CODES.HONEYCOMB)
04.@SuppressLint("NewApi")
05.@Override
06.publicvoidonClick(View v) {
07.PopupMenu popup = newPopupMenu(MenuActivity2.this, v);  //建立PopupMenu对象
08.popup.getMenuInflater().inflate(R.menu.menu_activity2,   //压入XML资源文件
09.popup.getMenu());
10.popup.setOnMenuItemClickListener(MenuActivity2.this);    //设置点击菜单选项事件
11.popup.show();                                            //显示菜单
12.}
13.});
(2)点击事件


view sourceprint?
01.@Override
02.publicbooleanonMenuItemClick(MenuItem item) {
03.switch(item.getItemId()) {
04.caseR.id.user_info:
05.Toast.makeText(MenuActivity2.this"You click user_info",
06.Toast.LENGTH_SHORT).show();
07.returntrue;
08.caseR.id.user_setting:
09.Toast.makeText(MenuActivity2.this"You click user_setting",
10.Toast.LENGTH_SHORT).show();
11.returntrue;
12.caseR.id.user_login:
13.Toast.makeText(MenuActivity2.this"You click user_login",
14.Toast.LENGTH_SHORT).show();
15.returntrue;
16.default:
17.returnfalse;
18.}
19.}
效果图:
4. 总结:
菜单主要分两种,OptionMenu和ContextMenu,只有浮动菜单(floating menu)和ActionMode菜单为ContextMenu。OptionMenu建立菜单的方法为在onCreateOptionMenu中inflate XML文件,在onMenuItemClick中设置点击事件(PopupMenu使用自身的setOnMenuItemClickListener设置),ContextMenu建立菜单的方法为在onCreateContextMenu中inflate XML文件(ActionMode在Callback中),在onContextItemClick中设置点击事件。
0 0