使用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。
第三个是优先级,第四个是标题。