来简书的第一篇文章,想了想就以这个作为开头了^^

概述

写自己的app时,发现NavigationView的默认菜单功能不支持类似OptionMenu那样点击后弹出二级子菜单的功能,思考了下想用PopupMenu来实现,现将遇到的坑和具体实现记录如下。

PopupMenu基本用法

这里推荐使用support-v7包下的PopupMenu,兼容更多版本且功能更丰富:

PopupMenu popupMenu = new PopupMenu(context, anchorView);

popupMenu.inflate(R.menu.xxx);

popupMenu.show();

popupMenu.setOnMenuItemClickListener(...);

NavigationView下弹出PopupMenu

上面构造函数的第二个参数anchorView表示popupMenu弹出时确定其位置的锚点。于是自然想到用NavigationView的menuitem来实现:

Menu navMenu = navigationView.getMenu();

MenuItem menuItem = navMenu.findItem(R.id.xxx);

anchorView = menuItem.getActionView();

完事了?还早着呢!编译后发现报错:

IllegalStateException: MenuPopupHelper cannot be used without an anchor

提示没有锚点。咦?我们不是传入了menuItem.getActionView()作为锚点么?

查询MenuItem的getActionView()方法源码后发现该方法返回的不是一个具体的控件或布局的view,所以导致popupMenu无法确定具体的锚点。

在网上搜索了一下解决方法,发现可以通过给NavigationView的menuItem传入一个具体的布局来实现锚点的定位,menu.xml代码如下:

xmlns:app="http://schemas.android.com/apk/res-auto">

...

android:id="@+id/nav_xxx"

android:icon="@drawable/nav_xxx"

android:title="@string/donate"

app:actionLayout="@layout/anchor"/>

...

注意命名空间,anchor.xml代码如下:

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="1dp" />

可见只是一个空的LinearLayout,仅用来定位。这里将height设为1主要是为了防止layout挤占menu的空间导致UI变形。完成后再编译运行,效果如下:

popupmenu1.gif

功能正常实现了^^

进阶:给PopupMenu加上icon

最早的PopupMenu也是可以像NavigationView里的menu一样给设置icon的,但后来google为了明确区分PopupMenu和PopupWindow的使用,将相应的方法给精简掉了。但别忘了我们使用的是support-v7包的PopupMenu,这里依然可以利用MenuPopupHelper来实现。

MenuPopupHelper popupHelper = new MenuPopupHelper(context,(MenuBuilder) menu,view);

popupHelper.setForceShowIcon(true);

其中第二个参数需要传入当前menu并转化为MenuBuilder类型,而PopupMenu类型本身不能转化,可用popupMenu.getMenu()来实现。第三个参数就是上文已经说过的锚点。然后调用popupHelper的setForceShowIcon(true)方法就可以强制item显示icon了。

这里还有两个小坑:

Android Studio 3.0以上版本调用MenuPopupHelper的以上两行代码时编译器会报“xxx can only be called from within the same library group...”。这应该是个bug,解决方法很简单,在调用以上两个方法的方法体前面加上@SuppressLint("RestrictedApi")的注释,如:

@SuppressLint("RestrictedApi")

private void showPopupMenu(){

...

}

填完上面的坑后,运行,发现还是不能显示icon?这是因为我们对popupMenu的自定义是在popupHelper里进行的,所以最后不能用popupMenu.show(),而是要调用

popupHelper.show();

好了大功告成,看看最终效果吧:

popupmenu2.gif

参考

android二级菜单ui,巧用PopupMenu实现NavigationView的二级子菜单相关推荐

  1. Android菜单:选项菜单+上下文菜单+子菜单

    菜单是人机交互的重要接口,在 Android SDK 中,提供了菜单类 android.view.Menu,以完成与菜单有关的操作. Android SDK 提供三种菜单,分别如下. 1)Option ...

  2. java ui代码实现_Java + Element-UI 实现简单的树形菜单

    一.简单入门级树形菜单实现(纯后台逻辑) 1.简介 (1)开发环境 IDEA + JDK1.8 + mysql 1.8 SpringBoot 2.2.6 + mybatis-plus 此处仅后台开发( ...

  3. Menu详解(二):利用XML生成菜单和子菜单

    前言:上篇,我们说了有关代码生成菜单和子菜单的方法,这里我们再讲讲有关利用XML生成菜单和子菜单的问题. 业精于勤,荒于嬉,行成于思,毁于随 (日拱一卒) 系列文章: 1.<Menu详解(一): ...

  4. 选项菜单_上下文菜单_子菜单_图标菜单_自定义菜单_联系人标记弹出菜单

    菜单控件<Menu > 选项菜单(Option Menu) 单击Menu实体按钮弹出,android中把它叫做option menu 上下文菜单(ContextMenu 是Menu的子接口 ...

  5. php在菜单栏里加子菜单,WordPress后台添加子菜单add_submenu_page()

    接上文:WordPress后台添加顶级菜单add_menu_page(),今儿再分享一下在 wordpress 后台侧边栏添加子菜单的方法,用到的函数是:add_submenu_page() 函数用法 ...

  6. vue伸缩效果_Vue2(三)实现子菜单展开收缩,带动画效果实现方法

    以前做这种操作就是简单的display:block,但现在用户的要求也越来越高,需要美观和动画感. 现在介绍用一种简单的方式来实现子菜单从上向下展开子菜单. 看下效果图: 点开效果: 其实原理比较简单 ...

  7. android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)

    菜单是应用程序中非常重要的组成部分,能够在不占用界面空间的前提下,为应用程序提供了统一的功能和设置界面,并为程序开发人员提供了易于使用的编程接口 Android系统支持三种菜单 选项菜单(Option ...

  8. 【Android基础知识】选项菜单、上下文菜单、子菜单的使用

    Android菜单类型 菜单是为了增加更多的功能,不占用屏幕的空间.Android中菜单类型有三类,选项菜单(OptionMenu).上下文菜单(ContextMenu).子菜单(SubMenu),下 ...

  9. 谷歌正式发布Android 12,UI更好看,应用更快,打造独属于自己的定制化属性

    焕然一新的Android 12 今年 5 月的 Google I/O 大会上,谷歌推出了 Android 12 系统,这是原生安卓系统史上最大的设计变化,从此旧貌换新颜. 不只是外观,Android ...

最新文章

  1. 图像处理------应用卷积一实现噪声消去
  2. linux/unix lsof用法
  3. Thread Join 讲解
  4. redis集成spring_将Redis集成到您的Spring项目中
  5. What's the difference between markForCheck() and detectChanges()
  6. 汤家凤:历年真题怎么用?接力题典怎么配合?黄金十月拼命干,提高很多分数不是梦!...
  7. 自定义video标签的大小
  8. 用计算机控制人造卫星属于,用计算机控制人造卫星属于 为什么人造卫星在高层大气...
  9. mysql 有没有minus_MySQL实现差集(Minus)和交集(Intersect)
  10. VS2015安装配置assimp和glm
  11. Spring @Transactional注解出错:CglibAopProxy - Unable to apply any optimisations to advised method
  12. 2 OsgEarth中实现PBR材质流程总结
  13. CSS浮动+背景图片+边框+文字排版+段落设置
  14. 直播系统源码搭建、手机直播源码APP平台开发制作
  15. zen cart产品分类及产品管理
  16. MO call与MT call
  17. ShaderJoy —— 烟花爆炸特效【GLSL】
  18. imagesize()函数获取图片信息
  19. 常用日本语1000句+简单用语
  20. 如何删除ActiveX控件

热门文章

  1. android之Activity关闭返回数据到启动他的页面
  2. Rtsp之海康设备预览回放url
  3. mark点Z3学习资料整理
  4. 谷歌浏览器如何启用java小脚本_各种浏览器开启JavaScript脚本方法
  5. 切换账号_微软 Edge 更新:自动切换工作 / 生活账号,移动端上线集锦功能
  6. EDI许可申请 简介
  7. ValueError: optimizer got an empty parameter list
  8. jdbc basedao mysql_Java使用JDBC连接mysql、sqlserver、orcle数据库的baseDao类
  9. python中execute函数_在excel中调用python函数
  10. python pyecharts 折线图_Python数据可视化之pyecharts实现各种图表