【Androidアプリ開発】コンテキストメニューを表示する

2023年2月7日

前回はAVDで日本語入力の手順を紹介しました。

【Androidアプリ開発】AVDで日本語入力
【Androidアプリ開発】AVDで日本語入力
前回はトースト表示を行いました。 今回は、AVDで起動したAndroidの日本語入力の方法を説明します。 AV…
http://nomux2.net/post-2272/

今回は、画面のアイテムを長押しした時に表示されるコンテキストメニューをやってみようと思います。

こんなやつです。

コンテキストメニューを実装する

コンテキストメニューは、オプションメニューと似ています。メニューのレイアウトそれを表示させたいアイテムに適用します。以下に例を表示します。

コンテキストメニューに表示する文字列です。

<resources>
    (省略)
    <string name="menu_context_description">詳細</string>
    <string name="menu_context_update">更新</string>
    <string name="menu_context_delete">削除</string>
</resources>

コンテキストメニューのレイアウトです。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/menuListContextDescription"
        android:title="@string/menu_context_description"/>

    <item
        android:id="@+id/menuListContextUpdate"
        android:title="@string/menu_context_update"/>

    <item
        android:id="@+id/menuListContextDelete"
        android:title="@string/menu_context_delete"/>

</menu>

MainAcivityに呼び出しを記載します。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //Todoリストを取得する
    val lvTodoList = findViewById<ListView>(R.id.lvTodoList)
    //Todoリストにコンテキストメニューを設定する
    registerForContextMenu(lvTodoList)

    ・・・
}

override fun onCreateContextMenu(menu: ContextMenu, view: View, menuInfo: ContextMenu.ContextMenuInfo) {
    //親クラスの同名メソッドの呼び出し
    super.onCreateContextMenu(menu, view, menuInfo)
    //コンテキストメニュー用xmlファイルをインフレイト
    menuInflater.inflate(R.menu.menu_context_todo_menu_list, menu)
}

override fun onContextItemSelected(item: MenuItem): Boolean {

    //長押しされたビューに関する情報が格納されたオブジェクトを取得
    val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
    //長押しされたリストのポジションを取得
    val listPosition = info.position
    //ポジションから選択されたTodoのIDを取得(!!は非nullに変換)
    val id = _listTodoID!![listPosition]

    when(item.itemId) {

        R.id.menuListContextDescription-> {
            //詳細を押されたときの処理
        }

        R.id.menuListContextUpdate-> {
            //更新を押されたときの処理
        }

        R.id.menuListContextDelete-> {
            //削除を押されたときの処理
        }
    }

    return super.onContextItemSelected(item)
}

それでは説明していきます。

コンテキストメニュー用のLayoutファイルを作成する

まず最初にlayoutファイルを作成します。

menuフォルダ右クリックして「New」-「Menu resource file」を選択します。

「menu」フォルダがない場合は、resディレクトリで右クリックをして「New」-「Android Resource Directory」を選択します。

以下のダイアログが表示されるので「Resource type」に「menu」を選択します。

自動で「Directory name」がmenuに変わるので「OK」をクリックします。

レイアウトを編集する

表示したいコンテキストメニューを入力します。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/menuListContextDescription"
        android:title="@string/menu_context_description"/>

    <item
        android:id="@+id/menuListContextUpdate"
        android:title="@string/menu_context_update"/>

    <item
        android:id="@+id/menuListContextDelete"
        android:title="@string/menu_context_delete"/>

</menu>

指定するのは「id」と「title」です。

ここでは「values/strings.xml」に指定したタイトルを使用しています。

コンテキストメニューの設定

コンテキストを表示したいviewをregisterForContextMenu関数で設定します。
そうすると長押しした時にonCreateContextMenu関数が呼ばれます。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //Todoリストを取得する
    val lvTodoList = findViewById<ListView>(R.id.lvTodoList)
    //Todoリストにコンテキストメニューを設定する
    registerForContextMenu(lvTodoList)
}

コンテキストメニューの表示

メニューを長押しした時に表示されるコンテキストメニューを設定します。

override fun onCreateContextMenu(menu: ContextMenu, view: View, menuInfo: ContextMenu.ContextMenuInfo) {
    //親クラスの同名メソッドの呼び出し
    super.onCreateContextMenu(menu, view, menuInfo)
    //コンテキストメニュー用xmlファイルをインフレイト
    menuInflater.inflate(R.menu.menu_context_todo_menu_list, menu)
}

先ほど作成したメニューのレイアウトをインフレイトします。
これで長押しするとメニューが表示されます。

コンテキストメニューを選択した時の処理

最後にコンテキストメニューを選択した時の処理を説明します。

コンテキストメニュのアイテムを選択するとonContextItemSelected関数が呼ばれます。

itemのmenuInfoプロパティにはリストビューの選択した位置が格納されていますのでそれを取得します。

itemIdプロパティは選択されたメニューのIDが格納されていますので、それを使って条件分岐します。

override fun onContextItemSelected(item: MenuItem): Boolean {

    //長押しされたビューに関する情報が格納されたオブジェクトを取得
    val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
    //長押しされたリストのポジションを取得
    val listPosition = info.position
    //ポジションから選択されたTodoのIDを取得(!!は非nullに変換)
    val id = _listTodoID!![listPosition]

    when(item.itemId) {

        R.id.menuListContextDescription-> {
            //詳細を押されたときの処理
        }

        R.id.menuListContextUpdate-> {
            //更新を押されたときの処理
        }

        R.id.menuListContextDelete-> {
            //削除を押されたときの処理
        }
    }

    return super.onContextItemSelected(item)
}

まとめ

今回の流れは、layoutファイルを作成し対象のオブジェクトに設定し呼び出す。という流れでした。

いろいろできるようになるとやりたことも増えて楽しくなってきますね。

ここまで読んで頂いてありがとうございます。