菜单之前是用户点击系统的菜单键才展示出来的,后来这个键渐渐被移除,菜单变成了点击任意的view都可以展示。菜单非为3种:

  1.Options menu and action bar  选项菜单和操作栏

  2.Context menu and contextual action mode 上下文菜单和上下文动作模式

  3.Popup menu  弹出式菜单

现在逐一介绍这3种菜单的使用方法:

1.Options menu

  这个菜单比较原始,它的实现必须通过点击actionbar 上的按钮或手机自带的菜单键才能显示。首先,在res文件目录下,新建文件夹menu,然后再menu文件夹中新建menu的xml文件,这里我的文件名为"option_menu".

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:id="@+id/add"
  4. android:icon="@mipmap/addition"
  5. android:title="添加"/>
  6. <item android:id="@+id/see"
  7. android:icon="@mipmap/eye"
  8. android:title="发现"/>
  9. <item android:id="@+id/state"
  10. android:icon="@mipmap/emoji"
  11. android:title="表情"/>
  12. </menu>

 我自己在mipmap文件夹中放了3张40*40 的小图标(你可以从图标网站自己去下载),这个xml文件比较简单。接着我们在activity中把这个xml填充成view。

  1. public class MainActivity extends AppCompatActivity {
  2.  
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. }
  8.  
  9. @Override
  10. public boolean onCreateOptionsMenu(Menu menu) {
  11. MenuInflater inflater = getMenuInflater();
  12. inflater.inflate(R.menu.option_menu,menu);
  13. return true;
  14. }
  15. }

这是点击actionbar右边的按钮弹出的界面截图,但奇怪的是我在xml配置的图标没显示出来 ̄︿ ̄。通过百度,原来是menu这个对象搞的鬼

我在这里打断点时可以发现menu在运行时实际上引用的是MenuBuilder对象。这个MenuBuilder对象和menu是什么关系呢? 通过sdk查询,他俩的关系是:

MenuBuilder------实现-----》SupportMenu(接口)-------继承--------》Menu(接口)。而在MenuBuilder这个类中控制图标显示的方法是:

初始时,mOptionlIconsVisible = false,我们只要调用setOptionalIconsVisible(true),就能解决问题。操作运行时的menuBuilder对象,很容易让我们想到用反射。。。我们写个方法,通过MenuBuilder的class对象,来调我们setOptionalIconsVisible方法。

懂反射的语法,上面的方法应该很容易就能看懂了。最后看看效果:

大功告成!接下来就来监听菜单的点击事件了,方法是onOptionsItemSelected(),见名思意,这个方法和onCreateOptionsMenu()方法的关键字都是option,通过androidstudio强大的提示功能,也不用去记全名。

这里我只写了菜单中其中一项的点击事件,其他的类似。提醒一点:这里的switch语句不像通常那样用break,而是用return true,有两个原因:1.我们用break,最后还是要在switch语句结束后,返回布尔值给方法,还不如在case 中直接返回。2:这一点更重要,方法要求返回布尔结果就是为了消费这次点击事件,true就是消费,false不消费,如果不消费,那么这个点击事件会继续传递给activity里的fragment。而我们这个简单到什么都没有,所有返回true还是false,没什么影响,但建议return true来消费这次点击事件。

好了,最简单的选项菜单已经介绍完了,接下来看看更高级一点的上下文菜单。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.Context menu

对于第一个optionmenu 只跟actionBar关系好的这个事实,让开发人员不满意:我一个界面这么多元素难道就不能弹菜单吗?那么上下文菜单的出现就可以让我们少些抱怨。上下文菜单分为两种:

(1) floating context menu  浮动上下文菜单:它的效果是当你长按控件时,会在屏幕中央出现一个列表。类似于你长按qq消息列表中的某一项,会弹出置顶、删除等选项。

先完成一个小目标,点击一个按钮,弹出浮动上下文菜单。

老规矩:定义个float_menu.xml。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item
  4. android:id="@+id/top"
  5. android:icon="@mipmap/up"
  6. android:title="置顶" />
  7. <item
  8. android:id="@+id/delete"
  9. android:icon="@mipmap/delete"
  10. android:title="删除" />
  11. </menu>

布局中加一个按钮:

这是activity中的代码:

长按按钮,出现的结果如图:

我的图标怎么又不见了!!!难道之前的那个setIconEnable()方法失灵了。真是到处是坑。我通过打断点查看menu这个对象,结果如图:

看看之前这里得到的是MenuBuilder对象,现在创建ContextMenu,就成了ContextMenuBuilder对象。我查了这个类,结果发现ContextMenuBuilder继承MenuBuilder,那就好办了,将setIconEnable()方法改一行就OK:

圈起来的就是获取父类的class对象,来看看结果:

可爱的图标终于又出现了。针对一个view弹出浮动菜单,除了不要忘记对控件注册上下文菜单,整体而言,还算简单。现在看看对listview 注册上下文菜单。别担心,更上面的代码有90%是一样的,不管怎么,把它做出来,也很有成就感。

1.先把布局中的按钮换成listview:

2.这是activity更改的代码,另外的两个方法onCreateContextMenu()和 setIconEnable() 都未做更改:

3.当你长按列表中任意一项出现的结果如图:

4.处理点击浮动菜单事件:

注意:如果是普通的view,红线那行是不需要的,其中info,position是长按项在list中的角标。

(2) contextual action mode 上下文操作模式,它会在屏幕顶部弹出 context action bar(简称CAB) .它的用处在于,你看到一段不错的文字,先把他复制下来,你长按控件就会在顶部出现CAB,操作完后再关掉CAB,很方便。

我们基于上面的listview再做修改来展示出CAB。

1.修改onCreate()里的代码:

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. listView = findViewById(R.id.listview);
  5. Random random = new Random();
  6. for (int i=0;i<array.length;i++){
  7. array[i] =String.valueOf(random.nextInt(1000));
  8. }
  9. //就因为这行代码,使按钮的长按事件与onCreateContextMenu建立了联系,所以非常重要
  10. ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,array);
  11. listView.setAdapter(adapter);
  12.  
  13. listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
  14. listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
  15. @Override
  16. public boolean onCreateActionMode(ActionMode mode, Menu menu) {
  17. Log.d(TAG,"onCreateActionMode");
  18. MenuInflater inflater = mode.getMenuInflater();
  19. inflater.inflate(R.menu.float_menu,menu);
  20. return true;
  21. }
  22.  
  23. @Override
  24. public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
  25. Log.d(TAG,"onPrepareActionMode");
  26. return false;
  27. }
  28.  
  29. @Override
  30. public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
  31. //长按控件调用的第一个方法。
  32. Log.d(TAG,"onItemCheckedStateChanged");
  33. }
  34.  
  35. @Override
  36. public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
  37. Log.d(TAG,"onActionItemClicked");
  38. switch (item.getItemId()){
  39. case R.id.top:
  40. Toast.makeText(MainActivity.this, "置顶", Toast.LENGTH_SHORT).show();
  41. mode.finish();
  42. return true;
  43. default:
  44. return false;
  45. }
  46. }
  47.  
  48. @Override
  49. public void onDestroyActionMode(ActionMode mode) {
  50. Log.d(TAG,"onDestroyActionMode");
  51. }
  52. });
  53. }

上面创建setMultiChoiceModeListener()的方法回调顺序,我特地进行了调整成了它回调的顺序,有前到后。5个回调中,当你长按listview中的某一项是,最先回调的是前3个方法,点击点击了头部CAB后,才会调用后两个。其中mode.finisha()如果不加进去,那么头部栏是不会消失的。最终结果图为:

这里只有图标,文字不见,我没有追究了,哎!这种从最上面弹出的actionbar更高级些。它把我们从点击控件到弹出bar,再到点击菜单项的全部过程用5个回调,解析的很全面。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.Popup menu  弹出式菜单:

熟悉popopwindow 的情形下,使用popupmenu应该会觉得很容易。在默认情形下:popup menu 显示在控件上面,如果空间不过,则在下方显示,当前也可以通过设置setGravity()来设置它跟锚的gravity值。它的使用与第一种options menu99%相似。

将layout中的listview再改回button,这就不上截图了,直接看acvity中的代码就一目了然。

  1. public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener{
  2. private static final String TAG = "MainActivity";
  3. private Button showPopMenuBtn;
  4.  
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. showPopMenuBtn = findViewById(R.id.showPopmenuBtn);
  10. showPopMenuBtn.setOnClickListener(new View.OnClickListener() {
  11. @Override
  12. public void onClick(View v) {
  13. PopupMenu popup = new PopupMenu(MainActivity.this,v);
  14. MenuInflater inflater = popup.getMenuInflater();
  15. inflater.inflate(R.menu.option_menu,popup.getMenu());
  16. setIconEnable(popup.getMenu(),true);
  17. popup.show();//这里给popup设置监听事件,而整个activity实现了监听。
  18. popup.setOnMenuItemClickListener(MainActivity.this);
  19. }
  20. });
  21. }
  22.  
  23. public void setIconEnable(Menu menu, boolean isVisible){
  24. if (menu !=null){
  25. try {
  26. Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible",boolean.class);
  27. method.setAccessible(true);
  28. method.invoke(menu,isVisible);
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34.  
  35. @Override
  36. public boolean onMenuItemClick(MenuItem item) {
  37. switch (item.getItemId()){
  38. case R.id.add:
  39. Toast.makeText(MainActivity.this,"添加",Toast.LENGTH_SHORT).show();
  40. return true;
  41. default:
  42. return false;
  43.  
  44. }
  45. }

运行结果如图:

从popup menu设计初衷上,也只是为了对单个控件选定进行了操作,跟上下文菜单中的浮动上下文菜单功能是一模一样的,甚至官方推荐你用第二种。只不过由于popwindow自身的属性,所以让他在menu中也占了一席之地。我自人以为,如果你想点个控件,让它弹出菜单,用第二种是最好的。其中第二种上下文菜单中的浮动菜单比较简单,但可以满足非常多的普通需求,当你需要更详细的交互过程控制,就考虑上下文菜单中第二种操作模式。

最后一点:不要被这篇博客的滚动条给吓到,里面有很多代码、结果截图,真正有用的代码少的可怜。( ̄︶ ̄)

安卓menu的介绍与使用的更多相关文章

  1. 安卓Menu键的问题

    近期开发中有须要Menu键,结果发现了一个非常尴尬的问题.我的測试机上有Menu键.可是測试平板上没有,队友的測试机上竟然也没有Menu键.这着实有些尴尬... 上网谷歌之后才发现问题所在: 仅仅有在 ...

  2. 打造属于自己的安卓menu

    首先,我们来看看这张图吧 看下面的menu菜单,是原装的菜单,好丑陋哦,类似于小编这么爱美的人来说,纯粹就是天大的打击,接受不起.于是,小编就发奋图强,努力,努力,再努力,终于,将菜单改的漂亮了一点, ...

  3. 安卓AndroidManifest.xml介绍

    先说一下,我的开发环境为Eclipse 3.7.1 + Android SDK + Android 1.5(API level3) Android最大的一个特点,就是用xml文件来配置,这个演习了Ja ...

  4. CAD梦想看图6.0安卓版详情介绍

    下载安装 MxCAD6.0(看图版).2018.10.22更新,扫描下面二维码,安装CAD梦想看图:   下载地址: http://www.mxdraw.com/help_8_20097.html 软 ...

  5. 安卓广播api介绍,给自己理清楚概念

    广播接收器类概述 这是用于接收由sendBroadcast()发送intent的基类.这个类一般都会被继承重写里面的onReceive()方法..如果您不需要跨应用程序发送广播,请考虑使用LocalB ...

  6. Android 中常见控件的介绍和使用

    1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...

  7. Android4.0 -- UI控件之 Menu 菜单的的使用(一)

      这一讲开始我们来讲一下Android中菜单的使用方法,菜单是应用中的普通的组件,主要是提供友好和专注的用户体验,你可以在你的Activity中使用 Menu APIs 来提供用户动作和其他选项的操 ...

  8. Python:GUI之tkinter学习笔记1控件的介绍及使用

    相关内容: tkinter的使用 1.模块的导入 2.使用 3.控件介绍 Tk Button Label Frame Toplevel Menu Menubutton Canvas Entry Mes ...

  9. [Android] 通过Menu实现图片怀旧、浮雕、模糊、光照和素描效果

        因为随手拍项目想做成类似于美图秀秀那种底部有一排Menu实现不同效果的功能,这里先简介怎样通过Menu实现打开相冊中的图片.怀旧效果.浮雕效果.光照效果和素描效果.后面可能会讲述怎样通过Pop ...

随机推荐

  1. python多重继承的属性和方法调用顺序问题和对迭代器的初步理解

    推荐阅读:https://www.cnblogs.com/bigb/p/11650707.html 计算机学习的一个好办法就是自己将代码跑一遍,了解代码的运作顺序和原理(主要弄懂 函数作用,传入参数, ...

  2. hdu1732 Pushbox bfs 细节比较多,需要注意

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1732/ 题目就是推箱子游戏,有三个箱子和三个洞,最终目标状态就是三个箱子到三个洞中,所以我们搜索的状态就是人的位 ...

  3. redhat7安装

    ------------恢复内容开始------------ 新建虚拟机向导(自定义) 指定虚拟机安装位置,把他放在固态硬盘提升他的运行速度(不推荐,一般将位置定为非系统盘) 选择系统镜像文件 开机选 ...

  4. Alpine Linux 常用命令

    一:Alpine Linux开启SSH远程登陆 1.简介: 最重要的一个服务了,远程登陆需要用它,文件传输需要用它,必备功能.不管你是在实体机上跑,虚拟机上跑,docker里面跑,这个都是必须的. 2 ...

  5. javascript正则表达式入门先了解这些

    前言 此内容由学习<JavaScript正则表达式迷你书(1.1版)>整理而来(于2020年3月30日看完).此外还参考了MDN上关于Regex和String的相关内容,还有ECMAScr ...

  6. 机器学习中的 7 大损失函数实战总结(附Python演练)

    介绍 想象一下-你已经在给定的数据集上训练了机器学习模型,并准备好将它交付给客户.但是,你如何确定该模型能够提供最佳结果?是否有指标或技术可以帮助你快速评估数据集上的模型? 当然是有的,简而言之,机器 ...

  7. ARDUINO UNO数字引脚端口上电后不稳定状态。

    ARDUINO UNO数字引脚端口上电后不稳定状态. 在使用4*4矩阵键盘时,遇到了输入端的电平无法稳定,一直被识别为高电平. 在发现这一问题后,首先检查程序是否出错.检查后发现程序没有任何问题. 于 ...

  8. css 动画 transition和animation

    本文参考:http://www.ruanyifeng.com/blog/2014/02/css_transition_and_animation.html 1. transition基本用法: < ...

  9. Sql练习201908131742

    orderdt_jimmy表结构: sql查询: then amount end) t1, then amount end) t2, then amount end) t3 from orderdt_ ...

  10. win10配置易用命令行

    在 win10 下配置易用命令行 win10 相比 Linux 最大的短板之一是命令行. 这篇文章不会将 win10 配置到像Linux那样一行命令解决所有包的安装,只是从最大程度上方便开发. 我们主 ...