菜单是很多应用都会用到的组件,在Android系统中,菜单主要分为三类. 选项菜单 上下文菜单 弹出菜单
一 选项菜单 选项菜单是Activity的主菜单项集合.提供对应用产生全局影响的操作,比如:"设置", ''搜索"等
定义一个菜单,Android 推荐使用xml文件的方式来定义一个菜单.在项目的res/menu/目录内创建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">
<item android:id="@+id/menu_id1"
android:title="标签"
android:icon="@drawable/ic_menu"
app:showAsAction="never"/>
<item android:id="@+id/menu_id2"
android:title="设置"
app:showAsAction="never"/>
</menu>
<menu> 元素必须是该文件的根节点,可以包含一个或多个<item>和<group>元素
<item> 元素表示一个菜单项,该元素可包含嵌套的<menu>元素来创建子菜单,该元素支持多个属性:
andorid:id 菜单项独有的资源ID,让应用能够在用户选择菜单项是识别该菜单项.
android:icon 菜单项的图标
android:title 菜单项标题
app:showAsAction 菜单项在应用栏中的显示方式
<group> 元素是不可见的容器,用该元素可以对菜单项进行分类,使同类元素的状态和可见性一致.
在Activity里面重写onCreateOpotionsMenu()方法.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.menu_sample, menu)
return true
}
当用户从选项菜单中选择菜单项时,Android 系统会回调onOptionsItemSelected()方法.我们可以通过菜单项的唯一ID来识别.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_id1 -> {
true
}
R.id.menu_id2 -> {
true
}
else -> super.onOptionsItemSelected(item)
}
}
这是就可以弹出选项菜单和处理点击事件了.但是,默认的选项菜单会覆盖住Toolbar,如果我们想在Toolbar下面弹出选项菜单可以设置style.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
</style>
<style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow" >
<!--设置弹出位置,是否覆盖Toolbar,默认为true,即覆盖Toolbar-->
<item name="overlapAnchor">false</item>
<!--弹出层的背景颜色-->
<item name="android:popupBackground">#00dd00</item>
<!--弹出层水平方向上的偏移-->
<item name="android:dropDownHorizontalOffset">0dp</item>
<!--弹出层垂直方向上的偏移-->
<item name="android:dropDownVerticalOffset">0dp</item>
</style>
</resources>
有时,我们想在程序运行时更改一些菜单选项.我们可以重写onPrepareOptionsMenu()方法.在该方法中可以对菜单项做出一些修改,比如添加,移除或禁用. 在产生事件时,如果想更新菜单,必须调用invalidateOptionsMenu()方法来请求系统调用onPrepareOptionsMenu().
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
menu?.getItem(R.id.menu_id1)?.title = "aaa"
return true
}
二 上下文菜单 上下文菜单提供了很多操作,这些操作会影响界面中的特定的菜单项或上下文框架,任何视图都能拥有上下文菜单.
使用悬浮上下文菜单(类似对话框),当用户长按某个注册了上下文菜单的视图时,菜单会显示为一个悬浮列表.用户一次只能对一个菜单项执行关联操作.为视图注册上下文菜单请调用registerForContextMenu().创建悬浮的上下文菜单需要重写onCreateContextMenu()方法.
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
super.onCreateContextMenu(menu, v, menuInfo)
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.context_menu, menu)
}
当用户从悬浮的上下文菜单中选择菜单项时,系统会回调onContextItemSelected()方法
override fun onContextItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_edit -> {
true
}
R.id.menu_delete -> {
true
}
else -> super.onContextItemSelected(item)
}
}
三 弹出式菜单 弹出菜单锚定在视图中的一种菜单,如果空寂足够,它会显示在锚定视图的下方,否则显示在其上方.
创建一个弹出菜单需要实力化一个PopupMenu对象. 创建该对象需要一个Context和应锚定菜单的Viewpopip
val popup = PopupMenu(this, v)
popup.setOnMenuItemClickListener (PopupMenu.OnMenuItemClickListener { item ->
when (item.itemId) {
R.id.menu_edit -> {
true
}
R.id.menu_delete -> {
true
}
else -> false
}
})
val inflater: MenuInflater = popup.menuInflater
inflater.inflate(R.menu.actions, popup.menu)
popup.show()
处理点击事件必须实现一个PopupMenu.OnMenuItemClickListener接口,通过setOnMenuItemClickListener()方法将其注册到PopupWindow.