使用Kotlin的Android菜单
在本教程中,我们将使用Kotlin在我们的android应用程序中讨论和实现Android Menu类。
我们将看到菜单在屏幕上显示的不同方式。
Android菜单
菜单是一个UI组件,用于显示选项列表以执行快速操作。
Android中的菜单大致分为三种类型:
选项菜单–这些是最常见的菜单形式。
它们通常显示在工具列中。上下文菜单–这些是浮动菜单,当用户长按应显示菜单的小部件时会显示这些菜单
弹出菜单–这些显示在单击的小部件上方或者下方的锚点上。
可以在resources文件夹内定义Android菜单。
每个菜单都与一个图标和一个标题以及一个属性" showAsAction"相关联。
android:orderInCategory属性用于设置菜单中菜单项的顺序。
最高顺序占据最左侧的位置。
它接受一个整数值。
在下一节中,我们将使用Kotlin创建一个Android应用程序,其中将涵盖所有这些菜单类型。
项目结构
在res文件夹中,创建一个新的资源目录来保存菜单。
在创建的新菜单文件夹中,创建菜单资源布局文件:
代码
menu_main.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/agenda"
android:icon="@android:drawable/ic_menu_agenda"
android:orderInCategory="100"
android:title="Agenda"
app:showAsAction="never"
<item
android:id="@+id/call"
android:icon="@android:drawable/ic_menu_call"
android:orderInCategory="100"
android:title="Call"
app:showAsAction="always"
<item
android:id="@+id/add"
android:icon="@android:drawable/ic_menu_add"
android:orderInCategory="100"
android:title="Add"
app:showAsAction="ifRoom"
<item
android:id="@+id/compass"
android:icon="@android:drawable/ic_menu_compass"
android:orderInCategory="100"
android:title="Compass"
app:showAsAction="always"
<item
android:id="@+id/day"
android:orderInCategory="100"
android:title="Day"
app:showAsAction="always|withText"
</menu>
ifRoom值指示仅在有空间时显示菜单图标。
此优先级是第二低的。
从不值表示菜单图标在工具列/菜单布局中根本不会显示。
它位于溢出菜单中。
始终表示菜单图标。
withText表示将显示菜单文本。
我们可以合并以上两个值中的任何一个(不合并绝对值没有意义!)
菜单文件" popup_menu.xml"的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/one"
android:title="One"
<item
android:id="@+id/two"
android:title="Two"
<item
android:id="@+id/three"
android:title="Three"
</menu>
菜单项也可以分组。
我们可以在组上添加可检查的行为:popup_menu_group.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/my_move"
android:checkableBehavior="single">
<item
android:id="@+id/one"
android:title="One"
<item
android:id="@+id/two"
android:title="Two"
<item
android:id="@+id/three"
android:title="Three"
</group>
<group
android:id="@+id/second"
android:checkableBehavior="all">
<item
android:id="@+id/four"
android:checked="true"
android:title="Four"
<item
android:id="@+id/five"
android:title="Five"
<item
android:id="@+id/six"
android:title="Six"
</group>
</menu>
下面给出了" activity_main.xml"布局文件的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnContextMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Context Menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
<Button
android:id="@+id/btnPopUpMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Popup Menu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnContextMenu"
<Button
android:id="@+id/btnPopUpMenuGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Popup Menu Group"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnPopUpMenu"
</android.support.constraint.ConstraintLayout>
对于选项菜单,需要重写两个方法:onCreateOptionsMenu和onOptionsItemSelected。
在" onCreateOptionsMenu"中,我们使用MenuInflater类为XML菜单充气。
ContextMenu在特定视图上触发。
我们需要在该视图上调用registerForContextMenu。
这会触发onCreateContextMenu,在此我们在菜单列表中添加MenuItems。
选择任何文本菜单时onContextItemSelected被触发。
单击任何视图时将创建PopupMenu。
PopMenu本身通过使用menuInflater扩展菜单资源文件进行初始化。
为了显示PopupMenu,我们在其实例上调用show函数。
MainActivity.kt类的代码如下:
package com.theitroad.androidlymenus
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import android.support.v7.widget.PopupMenu
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
registerForContextMenu(btnContextMenu)
btnContextMenu.setOnLongClickListener {
openContextMenu(btnContextMenu)
true
}
btnPopUpMenu.setOnClickListener {
val popup = PopupMenu(this@MainActivity, btnPopUpMenu)
//Inflating the Popup using xml file
popup.menuInflater.inflate(R.menu.popup_menu, popup.menu)
popup.setOnMenuItemClickListener({
if (it.itemId == R.id.one) {
Toast.makeText(applicationContext, "One", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(applicationContext, "None", Toast.LENGTH_SHORT).show()
}
true
})
popup.show()//showing popup menu
}
btnPopUpMenuGroup.setOnClickListener {
val popup = PopupMenu(this@MainActivity, btnPopUpMenu)
//Inflating the Popup using xml file
popup.menuInflater.inflate(R.menu.popup_menu_group, popup.menu)
popup.setOnMenuItemClickListener({
if (it.itemId == R.id.four && it.isChecked) {
Toast.makeText(applicationContext, "Four. Was Checked", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(applicationContext, it.title, Toast.LENGTH_SHORT).show()
}
true
})
popup.show()
}
}
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
super.onCreateContextMenu(menu, v, menuInfo)
menu?.setHeaderTitle("Context Menu")
menu?.add(0, v?.id!!, 0, "Call")
menu?.add(0, v?.id!!, 1, "SMS")
menu?.add(1, v?.id!!, 0, "Search")
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onContextItemSelected(item: MenuItem?): Boolean {
when {
item?.title == "Call" -> {
Toast.makeText(applicationContext, "Call", Toast.LENGTH_LONG).show()
return true
}
item?.title == "SMS" -> {
Toast.makeText(applicationContext, "SMS", Toast.LENGTH_LONG).show()
return true
}
item?.title == "Search" -> {
Toast.makeText(applicationContext, "Search", Toast.LENGTH_LONG).show()
return true
}
else -> return super.onContextItemSelected(item)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.add -> {
Log.d("API123", "done")
return true
}
R.id.call -> {
Log.d("API123", "done")
return true
}
R.id.day -> {
Log.d("API123", "done")
return true
}
R.id.compass -> {
Log.d("API123", "done")
return true
}
R.id.agenda -> {
Log.d("API123", "done")
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
}
在onCreateContextMenu中:menu?.add(1,v?.id !!,0," Search")用于在上下文菜单中添加新菜单。
第一个参数是groupId。
因此,我们可以在菜单中拥有不同的菜单组。
第二个是菜单项ID。
第三个是优先级,第四个是标题。

