List popup window menusの実装

投稿日:  更新日:

List popup window menusの実装方法を紹介します。

スポンサーリンク

List popup window menusとは

ターゲットViewをクリックすることで、アンカーViewの下に表示されるメニューです。
※表示例はターゲット=アンカーViewになっています。

メニューの実態はApi 11で追加されたListPopupWindowクラスです。

ListPopupWindowはPopupWindow(パネルが浮き上がるような表示)とListView(アイテムを一覧表示)を組み合わせたもので、メニュー表示に特化して開発されたクラスではありません。

しかし、メニューと同等な振る舞いが期待できます。

Material Design ComponentsのMenusカテゴリに属し、メニューの表現方法の一つとして紹介されています。

アイテムを一覧表示する部分がListViewなので、メニューアイテムの指定にandroid.widget.ListAdapterを用いる点が大きな特徴です。

※現在(’21.08)ListViewはレガシー扱い、単独での使用は推奨されません。

スポンサーリンク

メニューの実装

実装はListViewそのものです。

サンプルの実装

配列でメニューのアイテムを用意したので、ListAdapterにArrayAdapterを用いています。

メニューのアイテムをListAdapter経由で、ListPopupWindow内のListViewへ登録するだけです。

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:ellipsize="end"
    android:maxLines="1"
    android:textAppearance="?attr/textAppearanceSubtitle1" />
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // ViewのクリックでList popup window menusを起動
        findViewById<Button>(R.id.btnSLT).setOnClickListener {
            openMenu(it)
        }
        findViewById<Button>(R.id.btnSRB).setOnClickListener {
            openMenu(it)
        }
    }

    fun openMenu(anchor: View) {
        val _items = arrayOf("Item 1", "Item 2", "Item 3")
        val _adapter = ArrayAdapter(this, R.layout.menu_item, _items)
        val _popup = ListPopupWindow(this)
        _popup.setAdapter(_adapter)
        _popup.setOnItemClickListener { parent, view, position, id ->
            _popup.dismiss()    // アイテムのクリックで自身を閉じる
        }
		_popup.anchorView = anchor
        _popup.show()
    }
}

注意点として、メニューのアイテムがクリックされた時に、自身を閉じる必要があります。ListPopupWindow#dissmiss( )が閉じる処理を行ってい部分です。

カスタマイズは他のListAdapter(Simple/CursorAdapterなど)を使ったり、アイテムのレイアウトを変更したり、ListViewと同じ方法が使えそうです。

サンプルの実行結果

図は上記で実装したList popup window menusの実行結果です。

List Popup Window Menusの実行結果

ターゲットViewをクリックすると、アンカーViewの下に左上を起点としたドロップダウンメニューが開いて、アイテムが現れます。ちなみに、サンプルはターゲット=アンカーViewになっています。

ドロップダウンメニューが画面の外へ出てしまうときは、メニュー全体が表示できる位置へ移動されます。

スポンサーリンク

アイテムのクリックイベント処理

AdapterView.OnItemClickListenerリスナーを実装し、ListPopupWindowオブジェクトへ登録します。

アイテムのクリックが行われるとAdapterView.OnItemClickListenerにコールバックが返ってきます。

引数のpositionがクリックされたアイテムの位置を示しています。後は位置に基づいて処理を行います(サンプルはToastを発行)。

アイテムを一覧表示している部分はListViewなので、イベントの処理方法はListViewと全く同じです。

class MainActivity : AppCompatActivity() {
    ...
    fun openMenu(anchor: View) {
        val _items = arrayOf("Item 1", "Item 2", "Item 3")
        val _adapter = ArrayAdapter(this, R.layout.menu_item, _items)
        val _popup = ListPopupWindow(this)
        _popup.anchorView = anchor
        _popup.setAdapter(_adapter)
        _popup.setOnItemClickListener { parent, view, position, id ->
            val _item = parent.getItemAtPosition(position) as String
            when(position) {
                0 -> {  // Item 1の処理
                    Toast.makeText(parent.context, _item, Toast.LENGTH_LONG)
                        .show() }
                1 -> {  // Item 2の処理
                    Toast.makeText(parent.context, _item, Toast.LENGTH_LONG)
                        .show() }
                2 -> {  // Item 3の処理
                    Toast.makeText(parent.context, _item, Toast.LENGTH_LONG)
                        .show() }
                else -> {}
            }
            _popup.dismiss()
        }
        _popup.show()
    }
}
スポンサーリンク

関連記事:

Material Design ComponentsにMenusというカテゴリがあります。 「Menus(メニュー)」なので、言葉のとおり、選択する項目を一覧表示する機能です。 Menusはメニューの表現方法によって、幾つかの種類があります。 このMenusの種類と特徴を紹介します。 ...
スポンサーリンク