【Android Studio】コンテキストメニューの作り方 – Kotlin編

この記事では コンテキストメニューの作り方を紹介します。
コンテキストメニューとは、ユーザーが画面を長押しすると表示されるメニューです。
以下のようなメニューを作成・表示します。

開発環境
Android Studio | Chipmunk 2021.2.1 |
Android Emulator | Nexus 4 (API 32) |
compileSdk / targetSdk | 32 |
minSdk | 16 |
プロジェクトについて
ContextMenuSample という名前のプロジェクトを作成して
- MainActivity.kt
- activity_main.xml
がある状態で実装していきます。
オプションメニューの作り方
1. レイアウトファイルの作成
Android Studio 画面左側のプロジェクト構造にある res フォルダの上で右クリックして、 New → Android Resource File を選択します。

File name に context_menu.xml と入力、Resource Type は Menu を選択します。

2. アイコンの用意
メニューに表示するアイコンを用意します。
今回は Android Studio から簡単に用意できる Vector アイコンを使います。
ご自身で用意したアイコン画像を使う場合は drawable フォルダに画像を置いてください。
Android Studio 画面の一番左側にある Resource Manager を開きます。

+ ボタンをクリックして Vector Asset を選択します。

Clip Art をクリックします。

phone を検索して OK を押します。

Next を押します。

Finish を押します。

同じ手順で email アイコンも追加します。

3. レイアウトの用意
context_menu.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/action_home" | |
android:title="ホーム" /> | |
<item | |
android:id="@+id/action_user" | |
android:title="アカウント" /> | |
<item | |
android:id="@+id/action_map" | |
android:title="地図" /> | |
<item android:title="お問い合わせ"> | |
<menu> | |
<item | |
android:id="@+id/action_tel" | |
android:icon="@drawable/ic_baseline_phone_24" | |
android:title="電話" /> | |
<item | |
android:id="@+id/action_mail" | |
android:icon="@drawable/ic_baseline_email_24" | |
android:title="メール" /> | |
</menu> | |
</item> | |
</menu> |
id 属性
クリックされた項目を識別できるように id を設定しておきます。
icon 属性
アイコン画像を指定します。(* 低い API ではアイコン画像が表示されない場合があります。)
title 属性
表示名です。
orderInCategory 属性
表示順序を指定することができます。(このサンプルでは使用していません。)
4. activity_main.xml の用意
今回は MainActivity 画面を長押しした時にメニューを表示させたいので、activity_main.xml の親レイアウトに id を用意しておきます。
activity_main.xml を開いて、7行目を追加します。
<?xml version="1.0" encoding="utf-8"?> | |
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".MainActivity" | |
android:id="@+id/rootLayout"> | |
</androidx.constraintlayout.widget.ConstraintLayout> |
5. オプションメニューを表示する
MainActivity.kt を開いて15・18~36行目を追加します。
package com.example.contextmenusample | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.view.ContextMenu | |
import android.view.MenuItem | |
import android.view.View | |
import android.widget.Toast | |
class MainActivity : AppCompatActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
registerForContextMenu(findViewById(R.id.rootLayout)) | |
} | |
override fun onCreateContextMenu( | |
menu: ContextMenu?, | |
v: View?, | |
menuInfo: ContextMenu.ContextMenuInfo? | |
) { | |
super.onCreateContextMenu(menu, v, menuInfo) | |
menuInflater.inflate(R.menu.context_menu, menu) | |
} | |
override fun onContextItemSelected(item: MenuItem): Boolean { | |
// when (item.itemId) { | |
// R.id.action_home -> | |
// R.id.action_user -> | |
// R.id.action_map -> | |
// } | |
Toast.makeText(this, "「${item.title}」が押されました。", Toast.LENGTH_SHORT).show() | |
return true | |
} | |
} |
15行目
registerForContextMenu(findViewById(R.id.rootLayout))
先ほど activity_main.xml に用意した id を使って「どのビューを長押しした時にコンテキストメニューを表示するのか」を登録します。
これを書かないとメニューが表示されないのでご注意ください。
18~25行目
onCreateContextMenu メソッドは、メニューを表示する時に呼び出されます。
27~36行目
onContextItemSelected メソッドは、項目が選択されたときに呼ばれます。
このサンプルでは選択された項目のタイトルを Toast 表示していますが、押された項目ごとに処理が変わる場合は28~32行目のように書くことができます。
他にもメニューを閉じた時に呼ばれる onContextMenuClosed メソッドがあります。
6. 完成
以上で完成です。

完成版のコード
- context_menu.xml
-
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
<?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/action_home" android:title="ホーム" /> <item android:id="@+id/action_user" android:title="アカウント" /> <item android:id="@+id/action_map" android:title="地図" /> <item android:title="お問い合わせ"> <menu> <item android:id="@+id/action_tel" android:icon="@drawable/ic_baseline_phone_24" android:title="電話" /> <item android:id="@+id/action_mail" android:icon="@drawable/ic_baseline_email_24" android:title="メール" /> </menu> </item> </menu>
- activity_main.xml
-
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:id="@+id/rootLayout"> </androidx.constraintlayout.widget.ConstraintLayout>
- MainActivity.kt
-
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package com.example.contextmenusample import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.ContextMenu import android.view.MenuItem import android.view.View import android.widget.Toast class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) registerForContextMenu(findViewById(R.id.rootLayout)) } override fun onCreateContextMenu( menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo? ) { super.onCreateContextMenu(menu, v, menuInfo) menuInflater.inflate(R.menu.context_menu, menu) } override fun onContextItemSelected(item: MenuItem): Boolean { // when (item.itemId) { // R.id.action_home -> // R.id.action_user -> // R.id.action_map -> // } Toast.makeText(this, "「${item.title}」が押されました。", Toast.LENGTH_SHORT).show() return true } }

このサイトでは「わかりやすく・シンプル」をモットーに、プログラミングの基礎からアプリ開発まで紹介します。
独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています。
主な使用言語:Java / Kotlin / PHP
>> 詳しいプロフィール
>> お問い合わせ
>> 書籍を出版しました!
COMMENT
投稿いただいたコメントは管理者の承認後に表示されます。
コードやエラーに関するご質問の場合は、以下の3点
をできるだけ具体的に必ず書いてください。
ご案内ありがとうございます。
ここで、例示されている2つのVectorAsset が、自機環境では選べませんでした。
追加のDowload が可能なのでしょうか?
開発環境は以下です。
Win11 Android Studio Giraffe
よろしくお願いします。
Shino
VectorAsset が選べないというのは2種類のアイコンだけが見つからないということでしょうか?
それとも全てアイコンが表示されない状態でしょうか?
特に追加のダウンロードは必要なく使えるものですので、インターネットの接続状況もご確認ください。
ありがとうございます。
Net接続の状態で、貴ページでご案内のように、Selection Icon 画面で、キーワードを[phone]として候補となるVector Asset は、異なった3つでした。
ご案内画面からして、Macと自機のWin環境では同一のVector Asset が現れないのでご案内をお願いしたところです。
図のように、キーワード[email]についても、同一のVector Asset は出現しませんでした。
Shino
詳細ありがとうございます。
私のWindows環境でもアイコンを選択できなかったので、以下のリンクよりアイコン画像をダウンロードしてご利用ください。
https://fonts.gstatic.com/s/i/materialicons/phone/v12/black-android.zip
https://fonts.gstatic.com/s/i/materialicons/mail/v16/black-android.zip
ダウンロードしたファイルを開いたら drawable フォルダにあるアイコンをプロジェクト内に置きます。
置き方は以下のページの「3. 画像を準備する」を参考にしていただければと思います。
https://codeforfun.jp/android-studio-catch-the-ball-2/
ありがとうございました。
図のように、ご案内記述と同じアイコンで表示できるようになりました。
お世話になりました。
Shino
ご報告ありがとうございます。
無事に表示できたとのこと良かったです!