【Android】画面コンポーネント / Menu ~ オプションメニュー ~

■ はじめに

Androidのメニュー(Menu)には、以下の2通りがある。
~~~~
1)オプションメニュー (Options menu)
 => 端末のMenuボタンを押すと表示されるメニュー

2)コンテキストメニュー (Context menu)
 => 長押しで表示されるメニュー
~~~~

今回は、「1)オプションメニュー (Options menu)」を扱う。

なお、「2)コンテキストメニュー (Context menu)」については
以下の関連記事を参照のこと。

画面コンポーネント / Menu ~ コンテキストメニュー
https://dk521123.hatenablog.com/entry/2018/08/30/200300

目次

【1】作成方法
 1)メニューをXMLで作成する
 2)メニューをコードから作成する
【2】メニューに関するあれこれ

【1】作成方法

* 以下の2種類ある 

1)メニューをXMLで作成する
2)メニューをコードから作成する

1)メニューをXMLから作成する

サンプル / Kotlin

手順

[1] 「res」ディレクトリを選択して、右クリックし、
 [New]-[Android Resource Directory]を選択

[2] 「Resource type」で「menu」を選択
 => 「Directory name」も「menu」になる
 => 「OK」ボタン押下
 => 「res」ディレクトリ内に「menu」ディレクトリが作成される

[3] [2] で作成した 「menu」ディレクトリを選択して、右クリックし、
 [New]-[Menu resource file]を選択

[4] File nameに任意の文字(今回は「memu_main」)を入力し、「OK」押下
 => menuディレクトリに「menu_main.xml」が追加

[5]  [4]で作成した「menu_main.xml」を開く

[6] 「Menu Item」を選択しドラッグアンドドロップで「Component Tree」のほうに選択し
 メニューを追加

[7] [6]で追加したメニューを選択し、以下を入力する
 + id : menu_add
 + title : Add

[8] 対象Activityを「プログラム部」を参考に作成し、
 メニュー追加とその際のイベント処理を書く

プログラム部

package com.dk.englishcards

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import kotlinx.android.synthetic.main.activity_main.*

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

    // ★メニュー表示★
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        super.onCreateOptionsMenu(menu)

        val inflater = menuInflater
        inflater.inflate(R.menu.menu_main, menu)
        return true
    }

    // ★メニューのアイテムを押下時の処理★
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.getItemId()) {
            //作成ボタンを押したとき
            R.id.menu_add -> {
                // ここに処理を書く
                return true
            }
            else -> {
                return super.onOptionsItemSelected(item)
            }
        }
    }

参考文献
https://www.usaco-pg.com/2017/09/11/kotlin-android-optionsmenu/
https://qiita.com/hirotann618/items/393c45a581f1b6b6178f

サンプル / Java

MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // オプションメニューが最初に呼び出される際に1度だけ呼び出される
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return true;
    }

    // オプションメニューの項目が選択された際に呼び出される
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean returnValue = true;
        int id = item.getItemId();
        switch (id) {
            case R.id.menuitem1:
                this.showMessage("Press Menu1");
                returnValue = true;
                break;
            case R.id.menuitem2:
                this.showMessage("Press Menu2");
                returnValue = true;
                break;
            default:
                returnValue = super.onOptionsItemSelected(item);
                break;
        }
        return returnValue;
    }

    private void showMessage(String message){
        Toast.makeText(
                this,
                message, Toast.LENGTH_SHORT).show();
    }
}

res/menu/menu_main.xml

<menu
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menuitem1"
        android:title="Menu1" />
    <item
        android:id="@+id/menuitem2"
        android:title="Menu2" />
</menu>

補足

メニューにアイコン画像を追加したい場合

 * アイコン用の画像「sampleIcon1」「sampleIcon2」を追加しておく
 * android:iconで画像を指定

    <item
        android:id="@+id/menuitem1"
        android:title="Menu1"
        android:icon="@drawable/sampleIcon1"/>

参考資料
http://techbooster.org/android/application/246/
http://androidguide.nomaki.jp/html/menu/menuMain.html

動作確認するには

 * 画面右上のアイコン(点々)を押下する

【2】メニューをコードから作成する

サンプル / Java

MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private static final int MENU_ID_MENU1 = (Menu.FIRST + 1);
    private static final int MENU_ID_MENU2 = (Menu.FIRST + 2);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // オプションメニューが最初に呼び出される際に1度だけ呼び出される
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // メニューアイテムを追加します
        menu.add(Menu.NONE, MENU_ID_MENU1, Menu.NONE, "Menu1");
        menu.add(Menu.NONE, MENU_ID_MENU2, Menu.NONE, "Menu2");
        return super.onCreateOptionsMenu(menu);
    }

    // オプションメニューが表示される度に呼び出される
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.findItem(MENU_ID_MENU2).setVisible(true);
        return super.onPrepareOptionsMenu(menu);
    }

    // オプションメニューの項目が選択された際に呼び出される
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean returnValue = true;
        int id = item.getItemId();
        switch (id) {
            case MENU_ID_MENU1:
                this.showMessage("Click Menu1");
                returnValue = true;
                break;
            case MENU_ID_MENU2:
                this.showMessage("Click Menu2");
                returnValue = true;
                break;
            default:
                returnValue = super.onOptionsItemSelected(item);
                break;
        }
        return returnValue;
    }

    private void showMessage(String message){
        Toast.makeText(
                this,
                message, Toast.LENGTH_SHORT).show();
    }
}

参考文献
http://www.adakoda.com/android/000085.html
http://techbooster.org/android/application/246/

【2】メニューに関するあれこれ

1)アイコンについて

追加1:build.gradleを更新する

[1] 「build.gradle (Module.app)」を修正し、[Build]-[Rebuild Project]を選択

build.gradle (Module.app)

dependencies {
    implementation 'com.google.android.material:material:1.2.0-rc01'
}

追加2:追加1でも欲しいアイコンがなかったら...

例:home(ic_menu_home) を追加する

* 対象ファイルは、以下にある
C:\Users\【Your-User-Name】\AppData\Local\Android\Sdk\platforms\android-xx\data\res\drawable-ldpi

[1] menu 画面を開き、Attributeの icon の隣のアイコンを押下
[2] 「Pick a resource」画面の右上の「+」アイコン押下
[3] 「Import Drawables」を押下し、対象アイコンのファイルを選択し、インポートする

https://stackoverflow.com/questions/10574404/i-cant-find-android-home-icon

2)アイコンを表示させる

[1] 「showAsAction」で「ifRoom」などを選択する

https://qiita.com/seekseep/items/5d7e73785c4bd6c91348

関連記事

画面コンポーネント / Menu ~ コンテキストメニュー
https://dk521123.hatenablog.com/entry/2018/08/30/200300