菜单知识点总结(kotlin)
菜单的分类
菜单是Android应用中重要且常见的组成部分,从Android3.0开始,android从一个专用的“菜单按钮”转变为提供一个应用栏来呈现常见的用户操作。
主要可以分为三类:选项菜单、上下文菜单/上下文操作模式以及弹出菜单。它们的主要区别如下:
选项菜单:Activity的主菜单项,用于放置对应用产生全局影响的操作,如
搜索/设置
。上下文菜单: 用户长按某一元素时出现的浮动菜单。它提供的操作将影响所选内容,主要应用于列表中的每一项元素(如长按列表项弹出删除对话框)。
上下文操作模式: 在屏幕顶部栏(菜单栏)显示影响所选内容的操作选项,并允许用户选择多项,一般用于对列表类型的数据进行批量操作。
弹出菜单: 以垂直列表形式显示一系列操作选项,一般由某一控件触发,弹出菜单将显示在对应控件的上方或下方。它适用于提供与特定内容相关的大量操作。
使用XML定义Menu
理论上而言,使用XML和Java代码都可以创建Menu。但是在实际开发中,往往通过XML文件定义Menu,这样做有以下几个好处:
XML可以可视化菜单结构
菜单内容与应用的逻辑代码分离
可以使用应用资源框架,为不同的平台版本、屏幕尺寸创建最合适的菜单(如对
drawable
、string
等系统资源的使用)要定义Menu,我们需要在
res
文件夹下新建menu
文件夹,用于存储与Menu相关的所有XML文件。
该菜单文件的构成元素包括:<menu>
、<item>
、<group>
。<menu>
: 菜单根节点,能够包含一个或多个<item>
和<group>
元素,是定义菜单项的容器。<item>
: 菜单项节点,用于定义MenuItem,可以嵌套<menu>
元素,以便创建子菜单。<group>
:<item>
元素的不可见容器(可选),可以使用它对菜单项进行分组,使一组菜单项共享可用性和可见性等属性。
XML菜单文件的示例代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><itemandroid:id="@+id/item_save"android:icon="@drawable/ic_settings"android:title="保存"app:showAsAction="ifRoom"/><itemandroid:id="@+id/item_settings"android:icon="@drawable/ic_settings"android:title="设置"/
</menu>
其中,<item>
是我们主要需要关注的元素,它的常见属性如下:
- android:id:菜单项
(MenuItem)
的唯一标识 - android:icon:菜单项的图标(可选)
- android:title:菜单项的标题(必选)
- android:showAsAction:指定菜单项的显示方式。常用的有
ifRoom
、never
、always
、withText
。
showAsAction的取值说明
取值 | 说明 |
---|---|
ifRoom | 只有在标题栏中有空间时才将此项放置其中。如果没有足够的空间容纳标记为ifRoom的所有项,标题栏显示不了的菜单项将显示在溢出菜单中 |
withText | 菜单项的文本和图标一起显示,可以将此值与其他值用竖线分隔共同起作用 |
never | 菜单项永远不显示在标题栏,而隐藏在溢出菜单中 |
always | 始终将此菜单项显示在标题栏。除非必须始终显示在标题栏,否则不要使用该值 |
collapseActionView | 将菜单项折叠到一个按钮中,选择按钮展开,一般与ifRoom一起使用 |
选项菜单
普通选项菜单
要创建选项菜单,首先需要在XML文件中定义各个菜单项,具体代码如下:
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><itemandroid:id="@+id/item_download"android:icon="@drawable/ic_downward"android:title="保存"app:showAsAction="ifRoom"/><itemandroid:id="@+id/item_settings"android:icon="@drawable/ic_settings"app:showAsAction="withText"android:title="设置"/>
</menu>
可以看到,我们在XML文件中定义了两个普通的菜单项。同时,每一个<item>
都有一个独特的showAsAction属性。
Activity通过重写onCreateOptionsMenu()
方法加载创建的XML菜单资源,在此方法中使用MenuInflater
类的inflate()方法将XML资源加载到Menu对象。除此之外,还可以使用add()
添加菜单项来动态加载菜单项,具体实现如下:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {//加载xml菜单资源var inflater:MenuInflater = menuInflaterinflater.inflate(R.menu.option_menu,menu)//动态加载菜单项menu?.add(Menu.NONE,Menu.FIRST,3,"帮助")?.setIcon(R.drawable.ic_help)//设置菜单添加图标有效setIconsVisible(menu,true)return true}
当用户从选项菜单中选择菜单项时,系统将调用onOptionsItemSelected()
,此方法将传递所选的MenuItem
对象,通过调用该MenuItem
对象的itemId
方法获取菜单项的id,具体实现如下:
override fun onOptionsItemSelected(item: MenuItem): Boolean {//处理菜单项的选择return when(item.itemId){R.id.item_download-> {Toast.makeText(this,"下载",Toast.LENGTH_LONG).show()true}R.id.item_settings-> {Toast.makeText(this,"设置",Toast.LENGTH_LONG).show()true}Menu.FIRST -> {Toast.makeText(this,"帮助",Toast.LENGTH_LONG).show()true}else -> super.onOptionsItemSelected(item)}}
运行效果如图所示:
默认情况下,即便在菜单XML
文件中定义了android:icon
属性,在溢出菜单中图标也不会显示,本案例使用反射的方法获取Menu
对象的setOptionalIconsVisible()
,调用该方法显示图标icon
,具体实现如下:
//使用反射方法显示图标private fun setIconsVisible(menu: Menu?, flag:Boolean){//判断menu是否为空if(menu != null){try {val method:Method = menu.javaClass.getDeclaredMethod("setOptionalIconsVisible", TYPE)//强制使用方法method.isAccessible//调用该方法显示iconmethod.invoke(menu,flag)}catch (e:Exception){e.printStackTrace()}}}
然后将此方法添加到onCreateOptionsMenu()
方法的return语句之前即可,具体实现如下:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {//加载xml菜单资源var inflater:MenuInflater = menuInflaterinflater.inflate(R.menu.option_menu,menu)//动态加载菜单项menu?.add(Menu.NONE,Menu.FIRST,3,"帮助")?.setIcon(R.drawable.ic_help)//设置菜单添加图标有效setIconsVisible(menu,true)return true}
上下文菜单及上下文操作模式
上下文菜单
通常上下文菜单是以浮动菜单的形式呈现的,用户长按(按住)一个支持上下文菜单的View时,菜单将以浮动列表的形式出现(类似于对话框)。 通常用户一次可对一个项目执行上下文操作(比如一个单独的控件或列表中的一项)。
Android提供了两种上下文操作菜单的方法。
- 使用浮动上下文菜单:当长按某个View时,显示为菜单项的浮动列表。
- 使用上下文操作模式:在屏幕顶部栏显示上下文操作栏选项。
1.创建浮动上下文菜单操作步骤
(1)注册菜单
通过调用registerForContextMenu()
注册与上下文菜单关联的View。如果将ListView
或GridView
作为参数传入,那么每个列表将会有相同的浮动上下文菜单。
registerForContextMenu(binding.etName)
(2)加载菜单资源
在Activity
或Fragment
中实现onCreateContextMenu()
,动态加载Menu
资源。当注册后的View收到长按事件时,系统将调用此方法。
override fun onCreateContextMenu(menu: ContextMenu?,v: View?,menuInfo: ContextMenu.ContextMenuInfo?) {super.onCreateContextMenu(menu, v, menuInfo)if (v?.id == R.id.et_name){//加载菜单XML资源val inflater:MenuInflater = menuInflaterinflater.inflate(R.menu.context_menu,menu)//动态创建菜单项
// menu?.add(Menu.NONE,Menu.FIRST,0,"拷贝")
// menu?.add(Menu.NONE,Menu.FIRST+1,0,"粘贴")
// menu?.add(Menu.NONE,Menu.FIRST+2,0,"清空")}}
(3)处理菜单项单击事件
在Activity
或Fragment
中实现onContextItemSelected()
,实现菜单项的单击逻辑。
override fun onContextItemSelected(item: MenuItem): Boolean {return when(item.itemId){R.id.item_copy-> {Toast.makeText(this,item.title,Toast.LENGTH_LONG).show()true}R.id.item_paste-> {Toast.makeText(this,item.title,Toast.LENGTH_LONG).show()true}R.id.item_clear -> {binding.etName.setText("")true}else -> super.onOptionsItemSelected(item)}}
上下文操作模式
上下文操作模式是ActionMode
对象的系统实现,当用户长按控件或选中复选框等组件时调用此模式,会在屏幕顶部出现上下文操作栏,显示用户对所选控件执行的操作。
创建上下文操作栏模式的上下文菜单操作步骤
(1)实现ActionMode.Callback
接口
在该接口的回调方法中,为上下文操作栏指定操作、响应菜单项的单击事件等。
// 上下文操作模式对象private var actionMode: ActionMode? = null// 实现ActionMode 中 CallBack回调接口val actionModeCallback: ActionMode.Callback = object : ActionMode.Callback {// 创建方法,在启动上下文操作模式startActionMode(Callback)时调用// 在此配置上下文菜单的资源override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {mode.menuInflater.inflate(R.menu.context_menu, menu)return true}// 在创建方法后进行调用override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {return false}// 菜单项被点击,类似onContextItemSelected()方法override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {when (item.itemId) {R.id.item_copy -> Toast.makeText(this@MainActivity, "拷贝", Toast.LENGTH_SHORT).show()R.id.item_paste -> Toast.makeText(this@MainActivity, "粘贴", Toast.LENGTH_SHORT).show()R.id.item_clear -> binding.etName.setText("")else -> {}}return true}// 上下文操作模式结束时被调用override fun onDestroyActionMode(mode: ActionMode?) {actionMode = null}}
该接口的回调方法与选项菜单的回调方法基本相同,只是需要传递与事件相关联的ActionMode
对象。onActionItemClicked()
方法用于处理菜单项的单击事件,与onContextItemSelected()
类似。当系统销毁操作模式时,需要在onDestroyActionMode()
方法中将actionMode
变量设置为null。
(2)启动上下文操作模式
在用户名的EditView
控件的长按事件中调用startActionMode()
启动上下文操作模式,具体实现如下:
binding.etName.setOnLongClickListener(View.OnLongClickListener {if (actionMode!=null){return@OnLongClickListener false}actionMode = startActionMode(actionModeCallback)view.isSelectedreturn@OnLongClickListener false})
调用startActionMode()
方法返回ActionMode
对象,通过该对象响应上下文操作栏的事件。
弹出菜单
PopupMenu
是依赖View存在的模态菜单。如果空间足够,它将显示在相应View的下方,否则显示在其上方。
弹出菜单适用于:
- 为特定内容密切相关的操作提供溢出式菜单;
- 提供类似
Spinner
控件,但不保留永久选择的下拉菜单。
弹出菜单操作步骤:
(1)创建菜单资源文件
在res/menu
目录下创建PopupMenu
的XML
资源文件。
(2)创建并加载弹出菜单
在EditText
控件的单击事件方法中实例化PopupMenu
对象,传递当前上下文对象及绑定的View对象,然后调用MenuInflater.inflate()
方法加载菜单XML
文件,调用PopupMenu
的setOnMenuItemClickListener()
设置单击菜单项的事件监听器,最后调用show()
方法显示菜单。
binding.etPhone.setOnClickListener(View.OnClickListener {//创建弹出菜单对象(最低版本11),第二个参数是绑定的那个viewval popup:PopupMenu = PopupMenu(this,it)//获取菜单填充器val inflater:MenuInflater = popup.menuInflater//填充菜单inflater.inflate(R.menu.popup_menu,popup.menu)//绑定菜单项的单击事件popup.setOnMenuItemClickListener(this)//显示弹出菜单popup.show()})
(3)处理菜单项的OnMenuItemClick
事件
MainActivity
类实现PopupMenu.OnMenuItemClickListener
接口,重写onMenuItemClick()
回调方法,当用户选择菜单项时,系统调用onMenuItemClick()
进行处理。
// PopupMenu菜单项的点击事件override fun onMenuItemClick(item: MenuItem?): Boolean {when(item?.itemId){R.id.item_copy -> Toast.makeText(this,"复制...",Toast.LENGTH_SHORT).show()R.id.item_paste -> Toast.makeText(this,"粘贴...",Toast.LENGTH_SHORT).show()else -> {}}return false}
菜单知识点总结(kotlin)相关推荐
- 【微信公众号】菜单知识点
1.微信公众平台新增了个性化菜单接口,开发者可以通过该接口,让公众号的不同用户群体看到不一样的自定义菜单.该接口开放给已认证订阅号和已认证服务号.出于安全考虑,一个公众号的所有个性化菜单,最多只能设置 ...
- Kotlin学习笔记 第四章 Java调用Kotlin
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- Kotlin学习笔记 第二章 类与对象 第九节 泛型
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- Kotlin学习笔记 第一章开始 第二章 基础
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 本系列为参考Kotlin中文文档 https://download.csdn.net/dow ...
- Kotlin入门(2)让App开发变得更容易
上一篇文章介绍了如何搭建Kotlin的开发环境,可是这个开发环境依然基于Android Studio,而在Android Studio上使用Java进行编码,本来就是理所应当的,何必还要专门弄个Kot ...
- 《Kotlin从小白到大牛》第28章:项目实战1:开发PetStore宠物商店项目
第28章 项目实战1:开发PetStore宠物商店项目 前面学习的Kotlin知识只有通过项目贯穿起来,才能将书本中知识变成自己的.通过项目实战读者能够了解软件开发流程,了解所学知识在实际项目中使用的 ...
- Kotlin中Int和 Int? 以及 IntArray 和 Array的问题
开篇 之前文章中提到过,kotlin 的形参如果不加?那么会默认为不为空. 这个小知识点在 kotlin 编译的时候其实很有用的,我们拿java中的 int和 Integer 来举例. Integer ...
- 开发你的第一个 Android 应用
题图 | Technology vector created by stories - www.freepik.com 以下内容节选自经典权威 Android 入门与进阶图书 <Android编 ...
- 继往开来:Google I/O 21 Android Gradle Plugin 更新总结
距离 Google I/O 2021 已经过去了将近一个月,最近几天捋了捋关于 Android Gradle Plugin(AGP)方面的东西,主要集中在 "What's new in An ...
- 豆瓣评分 8.6,近 5 万读者学习的 Android 经典最新版出版,承载无数程序员的回忆......
题图 | 新的小绿人 © Google "出色向导" 对新手来说,学习 Android 开发一开始会很难.就像初次踏入异国他乡一样,即使会说当地语言,一开始也绝不会有舒服自在的感觉 ...
最新文章
- 怎么自学python语言-怎样学好python
- 测验8: 程序设计方法学 (第8周)
- 现在有一个整数数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数...
- Nginx基本数据结构之ngx_hash_t
- Table边框使用总结
- matlab的和操作
- pppoe 服务器 无线,centos搭建pppoe拨号服务器
- XManager连接CentOS6.5
- timestamp显示毫秒_TimeStamp 毫秒和纳秒
- 题5 正确的Java垃圾回收说法
- linux 没有network服务,求助,network起不来
- android短信验证码登录,Android注册登录实时自动获取短信验证码
- idea中的常用快捷键(新手必看)
- 【总结】线性代数的本质 - 3
- mysql导入excel表_mysql怎么导入excel数据?
- photon四种同步方式_Photon——主从服务器负载均衡及策略
- 赛意SMOM和金蝶云星空单据接口对接
- 2014年3I工作室成员的正式名单
- 修复柱面要多少时间_宜昌平面设计培训多少钱大约要学习多长时间
- 【计算机视觉】图片拼接