菜单之前是用户点击系统的菜单键才展示出来的,后来这个键渐渐被移除,菜单变成了点击任意的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".

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/add"
android:icon="@mipmap/addition"
android:title="添加"/>
<item android:id="@+id/see"
android:icon="@mipmap/eye"
android:title="发现"/>
<item android:id="@+id/state"
android:icon="@mipmap/emoji"
android:title="表情"/>
</menu>

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

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu,menu);
return true;
}
}

这是点击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。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/top"
android:icon="@mipmap/up"
android:title="置顶" />
<item
android:id="@+id/delete"
android:icon="@mipmap/delete"
android:title="删除" />
</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()里的代码:

 protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listview);
Random random = new Random();
for (int i=0;i<array.length;i++){
array[i] =String.valueOf(random.nextInt(1000));
}
//就因为这行代码,使按钮的长按事件与onCreateContextMenu建立了联系,所以非常重要
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,array);
listView.setAdapter(adapter); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Log.d(TAG,"onCreateActionMode");
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.float_menu,menu);
return true;
} @Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
Log.d(TAG,"onPrepareActionMode");
return false;
} @Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
//长按控件调用的第一个方法。
Log.d(TAG,"onItemCheckedStateChanged");
} @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.d(TAG,"onActionItemClicked");
switch (item.getItemId()){
case R.id.top:
Toast.makeText(MainActivity.this, "置顶", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
} @Override
public void onDestroyActionMode(ActionMode mode) {
Log.d(TAG,"onDestroyActionMode");
}
});
}

上面创建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中的代码就一目了然。

public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener{
private static final String TAG = "MainActivity";
private Button showPopMenuBtn; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showPopMenuBtn = findViewById(R.id.showPopmenuBtn);
showPopMenuBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(MainActivity.this,v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.option_menu,popup.getMenu());
setIconEnable(popup.getMenu(),true);
popup.show();//这里给popup设置监听事件,而整个activity实现了监听。
popup.setOnMenuItemClickListener(MainActivity.this);
}
});
} public void setIconEnable(Menu menu, boolean isVisible){
if (menu !=null){
try {
Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible",boolean.class);
method.setAccessible(true);
method.invoke(menu,isVisible);
} catch (Exception e) {
e.printStackTrace();
}
}
} @Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.add:
Toast.makeText(MainActivity.this,"添加",Toast.LENGTH_SHORT).show();
return true;
default:
return false; }
}

运行结果如图:

从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. CentOS7 如何安装JDK(以及卸载)

    CentOS7 如何安装JDK(以及卸载) 1. 如何安装JDK? 购买云服务器后,会提供一个公网IP和内网IP,需要使用SSH工具连接到云服务器(推荐使用SecureCRT),随后就能在命令行中操作 ...

  2. 升级 nop 4.1 Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.

    Incorrect syntax near 'OFFSET'.  Invalid usage of the option NEXT in the FETCH statement. nop.web 项目 ...

  3. Python 聊天界面编写

    import os from tkinter import * import time os.chdir('E:\\actdata') def main(): def sendMsg():#发送消息 ...

  4. 正则表达式(R&Python)

    regular expression 1.R,strongly recommend this blog The table_info examples are following: du_mtime_ ...

  5. CVPR 2019细粒度图像分类竞赛中国团队DeepBlueAI获冠军 | 技术干货分享

    [导读]CVPR 2019细粒度图像分类workshop的挑战赛公布了最终结果:中国团队DeepBlueAI获得冠军.本文带来冠军团队解决方案的技术分享. 近日,在Kaggle上举办的CVPR 201 ...

  6. 吴恩达最新TensorFlow专项课程开放注册,你离TF Boy只差这一步

    不需要 ML/DL 基础,不需要深奥数学背景,初学者和软件开发者也能快速掌握 TensorFlow.掌握人工智能应用的开发秘诀. 以前,吴恩达的机器学习课程和深度学习课程会介绍很多概念与知识,虽然也会 ...

  7. 解决pycharm不能导入bs4模块问题

    问题描述: 在导入bs4模块时有报错提示 “ Traceback (most recent call last): File "E:/project/code/py-pengfu/py-pf ...

  8. 12c OCR corrupted results in CRS stack down.

    12c OCR corrupted results in CRS stack down. 1. check crsd.trc2017-03-21 16:14:44.667838 :  CRSOCR:2 ...

  9. Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现

    本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) https://developer.salesfo ...

  10. Python库的安装方式

    Python库的安装方式 1.Python库的自定义安装——找到相应网站,下载安装 示例:pywin32库安装 .exe,直接双击,自动识别安装目录 安装就可以了. 载入成功 2.Python库的工具 ...