Popup menusの実装方法を紹介します。
目次 [非表示]
ターゲットViewをクリックすることで、アンカーViewの下に表示されるメニューです。
※表示例はターゲット=アンカーViewになっています。

AndroidのMenu APIが提供するもので、Menu APIの「Popup menus」と同じ動作です。
メニューの実装
Popup menusの実装方法を静的・動的に分けて示します。
静的な実装はメニューの構成をmenuリソース(xmlファイル)で定義します。
このmenuリソースはres/menuフォルダに配置する決まりです。フォルダが無ければ作成してください。
メニューの定義はmenu要素の中にitem子要素を列記するだけです。
1 2 3 4 5 6 7 8 9 10 11 12 | <? xml version = "1.0" encoding = "utf-8" ?> < item android:id = "@+id/menu_item1" android:title = "Item 1" /> < item android:id = "@+id/menu_item2" android:title = "Item 2" /> < item android:id = "@+id/menu_item3" android:title = "Item 3" /> </ menu > |
上記のメニューの定義を、PopupMenuオブジェクトへ組み込みます。このPopupMenuオブジェクトを#show()することで、メニューが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) ... // ViewのクリックでPopup menusを起動 findViewById<Button>(R.id.btnSLT).setOnClickListener { openMenu(it, R.menu.menu_items) } findViewById<Button>(R.id.btnSRB).setOnClickListener { openMenu(it, R.menu.menu_items) } } fun openMenu(anchor: View, resId: Int) { val _popup = PopupMenu( this , anchor) _popup.inflate(resId) // メニューの定義を組み込み _popup.show() } ... } |
動的な実装(Menu#addで定義)
動的な実装はメニューを構成するアイテムをMenu#addメソッドで一つ一つ追加していく方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) ... // ViewのクリックでPopup menusを起動 findViewById<Button>(R.id.btnSLT).setOnClickListener { openMenu(it, R.menu.menu_items) } findViewById<Button>(R.id.btnSRB).setOnClickListener { openMenu(it, R.menu.menu_items) } } fun openMenu(anchor: View) { val _popup = PopupMenu( this , anchor) _popup.menu.apply { // groupID itemID order title add(Menu.FIRST, Menu.FIRST + 0 , Menu.NONE, "File" ) add(Menu.FIRST, Menu.FIRST + 1 , Menu.NONE, "Edit" ) add(Menu.FIRST, Menu.FIRST + 2 , Menu.NONE, "Help" ) // ※orderが同じ(Menu.NONEは0)時はadd順に表示 } _popup.show() } ... } |
サンプルの実行結果
図は上記で実装したPopup menusの実行結果です。
ターゲットViewをクリックすると、アンカーViewの下に左上を起点としたドロップダウンメニューが開いて、アイテムが現れます。ちなみに、サンプルはターゲット=アンカーViewになっています。
ドロップダウンメニューが画面の外へ出てしまうときは、メニュー全体が表示できる位置へ移動されます。
アイテムのクリックイベント処理
PopupMenu.OnMenuItemClickListenerリスナーを実装し、PopupMenuオブジェクトへ登録します。
アイテムのクリックが行われるとPopupMenu.OnMenuItemClickListenerにコールバックが返ってきます。
引数で渡されるMenuItemが保持するitemIdを使って、どのアイテムがクリックされたかを判断します。後は判断に基づいて処理を行います(サンプルはToastを発行)。
処理を行ったらtrueを返します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class MainActivity : AppCompatActivity(), PopupMenu.OnMenuItemClickListener { ... fun openMenu(anchor: View, resId: Int) { val _popup = PopupMenu( this , anchor) _popup.inflate(resId) _popup.setOnMenuItemClickListener( this ) // リスナーの登録 _popup.show() } override fun onMenuItemClick(item: MenuItem): Boolean { // リスナーの実装 return when (item.itemId) { R.id.menu_item1 -> { Toast.makeText( this , "Item 1" , Toast.LENGTH_LONG).show() true } R.id.menu_item2 -> { Toast.makeText( this , "Item 2" , Toast.LENGTH_LONG).show() true } R.id.menu_item3 -> { Toast.makeText( this , "Item 3" , Toast.LENGTH_LONG).show() true } else -> super .onOptionsItemSelected(item) } } } |
上記の例はPopupMenu.OnMenuItemClickListenerをMainActivityで実装しています。
関連記事: