Android Menu的基本使用
来源:互联网 发布:球球大作战挂机软件 编辑:程序博客网 时间:2024/06/06 03:36
在Android中,菜单项是比较常见的一种人机交互方式,通过设置菜单项,既可以节省布局控件,也可以实现更加人性化的操作(可以提供一种不断发掘探索的精神)。其实,关于菜单项,大家都已经见怪不怪了,在windows或者其他操作系统中,已经熟悉的不能再熟悉了,在Android中应用也是非常,例如QQ、微信等都有不少菜单。接下来,简单介绍一下菜单的基本使用。
1.创建选项菜单(Options Menu)
由官方API可知,,onCreateOptionsMenu方法有唯一的一个参数Menu,而通过Menu.add方法可以添加菜单项,从add的重载方法看,最长的含有4个参数(int groupId, int itemId,int order,CharSequence title),其中第一个参数表示菜单项的分组ID,用于带选项按钮的菜单,一般这个参数不需要特别设置,任何整数均可以,而且在测试过程中,发现这个参数引起的变化不明显。第二个参数是当前菜单项ID,相当于一个“身份证”,这个是比较重要的,可以通过这个ID来确认选择的是哪个menu。第三个参数是显示顺序,这个order和menu.xml文件中<item>中的order是一样的,其顺序为从左到右,从上到下。最后一个参数则是该menu的标题。同时要注意,Android中的menu最多可以显示6个,还有多余的则以more的形式显示。
简单的代码示例:
public boolean onCreateOptionsMenu(Menu menu) { menu.add(1,1,2,"one"); menu.add(1,1,2,"two"); return true;}2.带图像的menu
实现的menu带图像很简单,只需要使用setIcon方法就可以,但是在测试过程中发现即使加了这句语言,也不能实现menu带图像,跟度娘请教后才发现,还有个反射函数,才能将图像显示,这里直接把反射函数截取下来:
public boolean onPrepareOptionsMenu(Menu menu) { if (menu != null) { if (menu.getClass() == MenuBuilder.class) { try { Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { } } } return super.onPrepareOptionsMenu(menu);}3.menu点击事件监听
在开发中,menu常常是用来设置参数或者切换Activity来实现扩展功能的,因此menu的事件监听就比较重要,menu的监听方法有三种,最常用的是onOptionsItemSelected和onMenuItemClick这两种方法,第三种onMenuItemSelected方法其实是调用onOptionsItemSelected方法来实现的,这几种方法的使用也很简单。
3.1onOptionsItemSelected
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_0: break; case R.id.action_1: break; case R.id.action_2: break; case R.id.action_3: break; default: break; } return super.onOptionsItemSelected(item); }3.2onMenuItemClick
public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.action_0: break; case R.id.action_1: break; case R.id.action_2: break; case R.id.action_3: break; default: break; } return false; }4.带复选框的menu
带复选框的menu,需要用到addSubMenu方法,而这个方法返回值为一个Submenu,但是addSubMenu和add方法在使用上完全一致,通过查阅API可以清楚的看到,SubMenu也可以直接设置menu图像,同时还有两个方法setCheckable和setChecked,这两个方法的参数均是boolean类型的参数,前者表示是否将该menu设置为复选框形式,后者表示是否选中,那么如果想要将父菜单下的子菜单设置成复选框类型,是否需要将每一个子菜单设置setChecked方法呢?答案呢当然是否,前文提到的menu.add参数的第一个参数是groupId,代表组别,那么只需要将这些子菜单设置成同样的groupId,使用setGroupCheckable来设置这个groupId,第二个参数必须设置为true,而第三个参数为true,则代表设置为选项按钮效果,false带白哦设置成复选框效果。
public boolean onCreateOptionsMenu(Menu menu) { SubMenu fileSubMenu = menu.addSubMenu(1,1,2,"文件"); fileSubMenu.setIcon(R.drawable.little_animal_02); fileSubMenu.setHeaderIcon(R.drawable.little_animal_06); MenuItem menuItem = fileSubMenu.add(1,2,2,"新建"); menuItem.setCheckable(true); menuItem.setChecked(true); MenuItem openMenuItem = fileSubMenu.add(2,3,3,"打开"); MenuItem exitMenuItem = fileSubMenu.add(2,4,4,"退出"); exitMenuItem.setChecked(true); fileSubMenu.setGroupCheckable(2,true,true); return true; }5.具有上一节title的menu
具有的上一级title的menu,又叫上下文菜单,效果就是当你电机一个menu,出现该menu的子菜单选项,这个时候在这些菜单选项的上边儿会出现父菜单的标题。
效果如下:
实现起来也很简单,需要覆盖onCreateContextMenu方法,代码如下:
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.setHeaderTitle("上下文菜单"); menu.setHeaderIcon(R.drawable.little_animal_10); //添加3个上下文菜单项,Menu.NONE的值是0 menu.add(0,menuItemId++,Menu.NONE,"菜单1").setCheckable(true).setChecked(true); menu.add(20,menuItemId++,Menu.NONE,"菜单2"); //选中第二个选项按钮 menu.add(20,menuItemId++,Menu.NONE,"菜单3").setChecked(true); menu.setGroupCheckable(20,true,true); //添加袋子菜单的上下文菜单项 SubMenu sub = menu.addSubMenu(0,menuItemId++,Menu.NONE,"子菜单"); sub.add("子菜单1"); sub.add("子菜单2");}其中add方法中的参数和之前介绍的参数一致。
7.介绍完上述的常用的几种菜单,接下来介绍一些在使用过程中遇到的问题。
7.1menu的位置,我们在设置完一个menu时,点击会发现,menu会覆盖标题栏,这样会使得用户体验很差很差,而且也不美观,那么如何让menu下移,不覆盖标题栏呢?
通过摸索和查阅,发现是否覆盖标题栏涉及到主题的问题,需要在自定义一个主题,设置overlapAnchor为false,同时将该主题应用到AppTheme中,其实,通过自定义menu主题,我们可以自定义设置很多东西,例如menu背景颜色,menu和title的距离等。
具体的代码如下:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="android:overlapAnchor">false</item> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!--menu主题--> <item name="actionOverflowMenuStyle">@style/LYJMenuStyle</item> </style> <style name="LYJMenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow"> <!--是否覆盖Title--> <item name="overlapAnchor">false</item> <!--背景颜色--> <item name="android:popupBackground">@color/White</item> <!--menu与Title的距离--> <item name="android:dropDownVerticalOffset">5dp</item> </style>7.2通过menu.xml文件来设置menu
Android studio中很人性化的提供了这一方法,通过这一方法,我们可以很简单的设置menu,而不需要通过前面的大量的代码来手动添加menu(包括上下文菜单等),解决的很多问题,那么在创建好menu.xml文件后,该如何显示到主UI中呢,这就需要在onCreateOptionsMenu中装载此文件,通过getMenuInflater.inflate(R.menu.menu,null)方法来装载该mennu文件,参数为该menu文件ID。关于menu.xml文件的创建,需要在res文件夹下创建一个menu文件夹。下面的示例创建了一个上下文菜单。
<item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/action_settings" app:showAsAction="never"/> <item android:id="@+id/mode_select" android:title="模式选择" android:orderInCategory="100"> <menu> <item android:id="@+id/manual_mode" android:orderInCategory="100" android:title="手动模式"/> <!--app:showAsAction="never"/>--> <item android:id="@+id/automatic_mode" android:orderInCategory="100" android:title="自动模式"/> <!--app:showAsAction="never"/>--> </menu> </item>第二个<item>中又添加了两个menu,这样就可以实现上下文菜单,比起纯代码的书写来是不是很方便。
7.3再来介绍一下,如何设置手机的“menu”键和软件的menu键的关联
在使用手机的过程中,我们经常会发现,点击手机的硬触控也会触发软件的menu,比如很早之前的浏览器,那么这种功能是如何实现的呢?记得在之前,我写过一个关于如何实现自拍杆功能的博文,当时是为了自定义开发一个相机而实现自拍杆功能,那篇文章介绍了Android的中的一个比较强大的onKeyDown方法,可以用来实现手机的一些硬触发按键的监听功能,那么,实现menu的关联,也可以通过此方法。具体代码如下:
/** * 点击手机上的menu键Ω * */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode){ case KeyEvent.KEYCODE_MENU://按下"menu"键动作 //选项菜单已弹出,不再弹出新的窗口 if (state == 1) return false; //装载选项菜单布局 layout = getLayoutInflater().inflate(R.layout.menu_layout,null); //创建PopupWindows对象,并在指定位置弹出用于显示菜单的窗口 pop = new PopupWindow(layout,getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight()); //设置弹出窗口的置 pop.showAtLocation(layout, Gravity.BOTTOM,0,0); View home = layout.findViewById(R.id.home); //为"首页"菜单添加单击事件 home.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "单击定制菜单", Toast.LENGTH_SHORT).show(); //单击"首页"菜单项后,关闭选项菜单 pop.dismiss(); state = 2; } }); //弹出选项菜单后,将状态变量设为1,表示选项菜单已弹出 state = 1; break; case KeyEvent.KEYCODE_BACK: if (state == 1){ //如果选项菜单已弹出,关闭它 pop.dismiss(); //将状态变量设为选项菜单已关闭 state = 2; }else if (state == 2){ //如果选项菜单还没有显示,或已经关闭,则直接关闭当前activity finish(); } break; } //除"menu"和"back"按下事件,仍需调用activity类的onKeyDown方法来响应其他按键的按下事件 return super.onKeyDown(keyCode,event); }
——参考自《Android开发权威指南》
- Android Menu的基本使用
- Android Menu的使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- android的Menu使用
- js创建对象的方法
- fl2440添加rt3070wifi模块--关于sta模式
- double freeing of freed memory
- Unity3d之Animation(动画系统)
- Java MySQL 连接
- Android Menu的基本使用
- BitBlts, AlphaBlend, TransparentBlt, 和 StretchBlt 有 GPU 加速
- OpenGL 很细的介绍
- 折半查找法
- 江苏科技大学“FlySpiders”本创小组第二次比赛活动-----1组
- ACM 粗心永远AC不了系列——Demo Day|三维DP问题,机器人寻路,hiho一下第150周
- LEETCODE 77. Combinations
- 读书笔记——《模式识别 Pattern Recognition》
- MySQL 数据类型