android二级菜单ui,巧用PopupMenu实现NavigationView的二级子菜单
来简书的第一篇文章,想了想就以这个作为开头了^^
概述
写自己的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的二级子菜单相关推荐
- Android菜单:选项菜单+上下文菜单+子菜单
菜单是人机交互的重要接口,在 Android SDK 中,提供了菜单类 android.view.Menu,以完成与菜单有关的操作. Android SDK 提供三种菜单,分别如下. 1)Option ...
- java ui代码实现_Java + Element-UI 实现简单的树形菜单
一.简单入门级树形菜单实现(纯后台逻辑) 1.简介 (1)开发环境 IDEA + JDK1.8 + mysql 1.8 SpringBoot 2.2.6 + mybatis-plus 此处仅后台开发( ...
- Menu详解(二):利用XML生成菜单和子菜单
前言:上篇,我们说了有关代码生成菜单和子菜单的方法,这里我们再讲讲有关利用XML生成菜单和子菜单的问题. 业精于勤,荒于嬉,行成于思,毁于随 (日拱一卒) 系列文章: 1.<Menu详解(一): ...
- 选项菜单_上下文菜单_子菜单_图标菜单_自定义菜单_联系人标记弹出菜单
菜单控件<Menu > 选项菜单(Option Menu) 单击Menu实体按钮弹出,android中把它叫做option menu 上下文菜单(ContextMenu 是Menu的子接口 ...
- php在菜单栏里加子菜单,WordPress后台添加子菜单add_submenu_page()
接上文:WordPress后台添加顶级菜单add_menu_page(),今儿再分享一下在 wordpress 后台侧边栏添加子菜单的方法,用到的函数是:add_submenu_page() 函数用法 ...
- vue伸缩效果_Vue2(三)实现子菜单展开收缩,带动画效果实现方法
以前做这种操作就是简单的display:block,但现在用户的要求也越来越高,需要美观和动画感. 现在介绍用一种简单的方式来实现子菜单从上向下展开子菜单. 看下效果图: 点开效果: 其实原理比较简单 ...
- android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)
菜单是应用程序中非常重要的组成部分,能够在不占用界面空间的前提下,为应用程序提供了统一的功能和设置界面,并为程序开发人员提供了易于使用的编程接口 Android系统支持三种菜单 选项菜单(Option ...
- 【Android基础知识】选项菜单、上下文菜单、子菜单的使用
Android菜单类型 菜单是为了增加更多的功能,不占用屏幕的空间.Android中菜单类型有三类,选项菜单(OptionMenu).上下文菜单(ContextMenu).子菜单(SubMenu),下 ...
- 谷歌正式发布Android 12,UI更好看,应用更快,打造独属于自己的定制化属性
焕然一新的Android 12 今年 5 月的 Google I/O 大会上,谷歌推出了 Android 12 系统,这是原生安卓系统史上最大的设计变化,从此旧貌换新颜. 不只是外观,Android ...
最新文章
- 图像处理------应用卷积一实现噪声消去
- linux/unix lsof用法
- Thread Join 讲解
- redis集成spring_将Redis集成到您的Spring项目中
- What's the difference between markForCheck() and detectChanges()
- 汤家凤:历年真题怎么用?接力题典怎么配合?黄金十月拼命干,提高很多分数不是梦!...
- 自定义video标签的大小
- 用计算机控制人造卫星属于,用计算机控制人造卫星属于 为什么人造卫星在高层大气...
- mysql 有没有minus_MySQL实现差集(Minus)和交集(Intersect)
- VS2015安装配置assimp和glm
- Spring @Transactional注解出错:CglibAopProxy - Unable to apply any optimisations to advised method
- 2 OsgEarth中实现PBR材质流程总结
- CSS浮动+背景图片+边框+文字排版+段落设置
- 直播系统源码搭建、手机直播源码APP平台开发制作
- zen cart产品分类及产品管理
- MO call与MT call
- ShaderJoy —— 烟花爆炸特效【GLSL】
- imagesize()函数获取图片信息
- 常用日本语1000句+简单用语
- 如何删除ActiveX控件
热门文章
- android之Activity关闭返回数据到启动他的页面
- Rtsp之海康设备预览回放url
- mark点Z3学习资料整理
- 谷歌浏览器如何启用java小脚本_各种浏览器开启JavaScript脚本方法
- 切换账号_微软 Edge 更新:自动切换工作 / 生活账号,移动端上线集锦功能
- EDI许可申请 简介
- ValueError: optimizer got an empty parameter list
- jdbc basedao mysql_Java使用JDBC连接mysql、sqlserver、orcle数据库的baseDao类
- python中execute函数_在excel中调用python函数
- python pyecharts 折线图_Python数据可视化之pyecharts实现各种图表