今回はオプションメニューの使い方について見ていきます。

ナビゲーションメニューが増えてきたのであまり需要はないかな?と思いつつも、
使っているアプリも結構ありそうなので紹介してみます。

目次

開発環境
プロジェクトを作ろう
オプションメニューを作ろう
画面を作ろう
オプションメニューを表示しよう
オプションメニューをクリックしてみよう
オプションメニューのアイテムを常に表示してみよう
オプションメニューを無効化してみよう
オプションメニューを非表示にしてみよう

いつも通りプロジェクト一式はgithub にありますので、そちらも合わせて参考にしてみてください。

開発環境

Android Studio 3.4.1
JDK 1.8
Kotlin 1.3
macOS Mojave (Windows でも基本的には同じように開発できると思います。)

プロジェクトを作ろう

こちらの記事を参考にプロジェクトを作成してください。

Activityのテンプレートは「Empty Activity」を選択してください。

プロジェクト名は「OptionsMenuSample」にしましたが、お好きなものでOKです。

オプションメニューを作ろう

プロジェクトが立ち上がったら、早速オプションメニューを作っていきましょう!

メニューファイルを作ろう

オプションメニューもXMLファイルで作ります。

まずはメニュー用のディレクトリを用意する必要があるので、「res」ディレクトリを選択して、右クリックをしてください。

New -> Android Resource Directory を選択してください。
そうするとディレクトリ作成画面が表示されます。

「Resource type」で「menu」を選択してください。 すると、「Directory name」も「menu」になると思うので確認して「OK」をクリックします。

これでresのなかに「menu」ディレクトリが作成されているはずです。

次に、作成したmenuディレクトリのなかにXMLファイルを作っていきたいので、menuを選択して、右クリックします。
New > Menu resource file を選択します。

そうするとリソースファイル作成画面が表示されます。

File nameに「memu_main」と入力して、「OK」をクリックします。

これでmenu_main.xmlがmenuディレクトリに追加されているはずです。

メニューを作っていこう

では、作成した menu_main.xml を開いて、編集していきましょう。
XMLで書いたほうが早いような気もしますが、せっかくなのでレウアウトエディタで編集していきます。

まずは最初から作成されている「Settings」メニューは削除してしまいましょう。
項目を選択してDeleteキーで削除できます。

新しいメニュー項目を追加していきましょう。
Paletteの「Menu Item」を使っていきます。
他にもいろいろItemはありますが、今回はMenu Itemのみ取り扱っていきます。Searchなんかもそのうち扱ってみたいですね。

では、Menu Itemを選択したらドラッグアンドドロップで追加してあげればいいのですが、レイアウト画面上だとちょっとやりにくかったりもするので、「Component Tree」のほうに追加していきます。
元々ある「menu」の中に追加されるようにドラッグしてあげてください。

追加できたら、下記の図のように id と title を設定します。
id を「action_add」、title を「Add」とします。
(画像では他のメニューも追加されていますが、ここまではメニューはひとつだけある状態で大丈夫です)

では、同じ要領であとふたつメニューを追加していきましょう。

全部で3つのメニューになりますが、それぞれidとtitleは以下のように設定してください。

id title
1 action_add Add
2 action_delete Delete
3 action_save Save

今の状態でComponent Tree は以下のようになっているかと思います。

ここで各メニューの横に黄色いマークが出ているのがわかるかと思います。
これは警告なので動作には影響しないため放っておいてもいいのですが、一応直しておきましょう。

黄色いマークをクリックするとレイアウトエディアの下部に詳細が表示されます。

titleをハードコードしているよ、という警告になります。
この画面の下の方にいくと「Fix」ボタンがあるのですが、ここをクリックすることで簡単に直すことができます。

「Fix」ボタンを押すと以下のような画面が表示されて、strings.xmlの設定を追加することができます。

「Resource name」をidを同じものにしておきましょう。(なんでもいいのですが、わかりやすい名前にしておきましょう)

3つのメニューすべて同じように警告を直していきましょう。
黄色い警告マークが無くなったらOKです。

これで一番簡単な設定のメニューができました。

画面を作ろう

メニューが一応完成したので、MainActivityの画面を作成していきましょう。
と言っても、ここでは選択されたメニューの名前を表示したいだけなので、最初からあるTextViewをそのまま使っていきましょう。

textは「Please select options menu」としておきます。
文字サイズも少し大きくしたいので、textSize を 24spにします。

メニューを作成したときと同様に警告マークが付くと思うので、警告マークをクリックして同様にFixボタンからstringsを作っていきましょう。

ここではResouce name はdefault_textとしました。

以下のような状態になっていればOKです。

オプションメニューを表示しよう

現状ではエミュレータを起動して実行してもオプションメニューは表示されません。
表示されるようにしていきましょう。

MainActivityクラスの中に実装していくのでMainActivity.ktを開いてください。

onCreate()の下辺りに下記のようにオプションメニューを表示するためのメソッドである onCreateOptionsMenu()をオーバーライドします。
以下のようにメソッド名の一部を書くとコード補完ができると思うのでそちらを使ってください。

そうすると、以下のようなソースが追加されます。

このメソッドでは使いたいメニューのメニューファイルを指定してあげる必要があるので、以下のように書き換えてください。

menuInflater.infrate()とすることでメニューを指定します。
第一引数にはメニューのIDを指定するので、作成したmenu_mainを書いてあげればOKです。
第二引数には引数で渡されてくるmenuを指定してください。
最後に true を返すことでメニューが表示されるようになります。

エミュレータで確認してみましょう。

起動すると、以下のように右上にオプションメニューのアイコンが表示されているはずです。

アイコンをクリックして、以下のようにメニューが表示されていればOKです。

オプションメニューをクリックしてみよう

表示されるようになったので、項目をクリックする処理を実装していきましょう。

クリックしたときに呼ばれる onOptionsItemSelected() メソッドをオーバーライドします。

引数の item: MenuItem? にクリックされたメニュー項目が入ってくるのでそれを使って処理を振り分けていきます。

ざざっと書くと以下のようになります。

item?itemIdでメニュー項目のIDが取得できるので、それをwhenで処理を振り分けています。
今回はそれぞれ選択されたメニューの名前を表示するだけなので、when式の結果をmessageに代入しています。

messagetextView.textに入れてあげれば画面に表示されます。

最後のreturn super.onOptionsItemSelected(item)は規定の動作をする上で必要なのでそのまま使用します。

ここまでできたらエミュレータで確認してみましょう。
選択したメニューが画面に表示されればOKです。

オプションメニューのアイテムを常に表示してみよう

基本的な流れはできたので、少し表示に仕方を変えてみたいと思います。

Addのメニューをアクションバーに常に表示されるようにしたいと思います。

Addをアクションバーに表示してみよう

Addのメニューを選択して、Attributesの「ShowAsAction」の旗のマークをクリックします。
以下のようなメニューが表示されるので、「always」にチェックを入れて、「Apply」ボタンをクリックします。

そうすると、以下のようにアクションバーに「Add」が表示されるようになります。

このShowAsActionですがその他の項目は以下のようになっていますので、必要に応じて変えてみるといいと思います。

never アクションバーには配置しません。常に通常のメニューの中に表示されます。
always 常にアクションバーに項目を配置します。
ifRoom アクションバーに空きがある場合にのみ配置します。空きがない場合には通常のメニューのなかに表示されます。
collapseActionView 項目に関連付けられているアクションビューは折りたたみ可能です。
withText アクションバーに表示するときにタイトルも一緒に表示します。

「collapseActionView」はちょっと使ったことがないのでよくわかりません😓
「withText」は他の属性と合わせて使ったります。「always」や「ifRoom」と一緒に使うとアイコンも隣にタイトルを表示できるようになったります。ただし、余白が多い場合のみなので横画面にしたときに表示されるようです。

よく使うメニュー項目はアクションバーに常に表示させたりといったことができるので、いろいろ試してみるといいですね。

Addアイコンを表示してみよう

このままだとタイトルが表示されていますが、アクションバーにはできればアイコンを表示したいですよね。
その場合はアイコン画像を設定すればいいのですが、デフォルトで使えるものがいまいちいいものがないので作ってしまいましょう。

VectorAssetsという機能を使って、予め用意されているクリップアートを使って簡単にアイコンを作ることができます。

drawbleフォルダを右クリックして、New > Vecter assets を選択してください。

そうすると下記のような画面が表示されます。

クリップアートから画像を選択したいので赤丸のついているボタンをクリックしてください。

クリップアートの一覧が表示されるので、赤丸の入力ボックスから使いたいアイコンを検索します。

add で検索すると以下のようになるので、今回は赤丸で示しているアイコンを使ってみます。

最初の画面に戻るので次はアイコンの色を変更していきましょう。
Colorのところをクリックします。

カラーパレットが表示されますが、白なので右上にあるカラーコードに直接「FFFFFF」と入力して、「Choose」ボタンをクリックします。

アイコンが白になったのを確認して、Name を下図のように設定します。(Nameはなんでもいいのでわかりやすい名前にしておきましょう)

「Next」をクリックすると保存場所を聞かれるのでそのまま「Finish」ボタンをクリックします。

そうすると、drawbleフォルダのなかに「ic_add_white_24dp.xml」ができてると思います。
これでアイコン画像ができたのでメニューに適応させましょう。

下図のiconの項目の絵のマークをクリックします。

次のような画面が表示されるので作成したアイコン「ic_add_white_24dp」を選択して「OK」をクリックします。

そうすると「Add」を表示されていたメニューがアイコンに変わったのがわかると思います。

プレビュー画面では他のアイコンや文字が黒なので違和感がありますが、実際にエミュレータで起動すると白になるので大丈夫です。
なので、起動して確認してみましょう。

このように+マークが表示されればOKです!

オプションメニューを無効化してみよう

メニューの項目を状況に応じて無効化したいといった場合もあると思います。
そのやり方を見ていきましょう。

メニューが表示される前に呼ばれるonPrepareOptionsMenu()メソッドを使って表示の切り替えを行います。

引数で渡されてく menu から該当のメニュー項目をmenu?.findItem()を使って取得して、isEnabledプロパティをfalseにしてあげればOKです。
以下の例ではDeleteのメニューを無効化しています。

最後のreturn文は最初のままにしておけばいいと思います。

非表示にした項目を再度表示したい場合はisEnabledプロパティをtrueにすればOKです。

ではエミュレータで確認してみましょう。

このようにDeleteメニューが薄い表示になって押せなくなっていればOKです!

オプションメニューを非表示にしてみよう

メニュー項目の表示系をもう一つやってみましょう。
今度は非表示にしてみます。

先ほどと同様にonPrepareOptionsMenu()メソッドに書いていきます。

同様にメニュー項目をmenu?.findItem()を使って取得して、isVisibleプロパティをfalseにしてあげればOKです。

非表示にした項目を再度表示したい場合はisVisibleプロパティをtrueにすればOKです。

ではエミュレータで確認してみましょう。

こうですね、Addのアイコンが消えているのでOKです。

簡単でしたがオプションメニューの使い方を説明してみました。
アクションバーにサーチメニューを置くやり方なんかも今後取り扱っていけたらなぁと思いますが、他にもいろいろ書きたいこともあり。
時間はかかりますがおいおい記事にしてこうと思います。