このページの本文へ

これで作れる! Androidのアプリケーション 第6回

Androidアプリ内で表示されるメニューを作成する

2010年08月05日 12時00分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

アプリケーション内にメニューを作る

 Androidのアプリケーションではメニューキーを押すことで、アプリケーション独自のメニューを表示させられます。このメニューは普段は隠れていますが、メニューキーを押したときに画面の下部に表示されます。基本的にはアイコンとテキストから構成されていて、タップすると機能が実行されます。

 メニューは、xmlで記述して作ることもできますし、コードからメニューを生成することもできます。今回のサンプルでは、メインアクティビティとアイテム編集アクティビティの2ヵ所でメニューを利用しています。

世界時計ではメニューを2ヵ所で利用している。1つは左画面のメインアクティビティで、もう1つは右画面のアイテムの編集画面

 前者は設定やアイテム追加、アプリケーションの終了などがあり、後者では、設定を保存することなく終了させる取り消し機能とアイテム自体の削除の2つの項目があります。アイテムの削除を編集画面に持ってきたのにはいくつか理由があります。1つは、メイン画面ではアイテムを選択した状態を表すことができないため、どれを削除するのかを指定するのが面倒であること(利用者、コード書く自分両方とも)、簡単に削除できるのもユーザーインターフェースとしてはいいものとは言いがたいので、個々のアイテムの編集画面に移行したのちに削除する仕組みにしました。

 メイン画面のメニュー表示は、初期に書いたものであるため、コードで項目を生成させています。これに対して、アイテム編集画面のメニューは、xmlを使って記述してあります。本来なら両方ともxmlにすべきでしょうが、サンプルという性格上、コードによる記述を残してあります。

メニューで発生するタイミング

 アプリケーション内で、ユーザーがメニューキーを押したとき、以下のようなイベントが発生します。

onCreateOptionMenu
onPrepareOptionMenu
onOptionMenuItemSelected

 最初の「onCreateOptionMenu」は、初めてメニューキーが押されたときのみに呼び出されるもので、通常はここでメニューを生成させます。次の「onPrepareOptionMenu」は、メニューが表示される直前に毎回呼び出されます。ここでは、状態に合わせてメニュー項目の有効、無効などを設定します。最後の「onOptionMenuItemSelected」は、ユーザーがメニュー項目のどれか1つをタップしたあとに呼び出されるものです。

 メニューは、基本的にはユーザーの操作により呼び出されます。このため、あらかじめタイミングを想定することはできません。必要なデータなどがあるなら、onCreateOptionMenuの中で生成するか、あるいはメニューを表示させるアクティビティのonCreateなどで準備しておく必要があります。

コードによるメニューの生成

 まずは、コードを使ってメニューを作る場合を見てみることにしましょう。WorldClock.javaの233行目からが対応するコードになります。

@Override
public boolean onCreateOptionsMenu( Menu menu ) {
  MenuItem itemAdd = menu.add( 0, MENU_ITEM_ADD, 0, R.string.menu_item_add );
  MenuItem itemSet = menu.add( 0, MENU_ITEM_SET, 0, R.string.menu_item_set );
  MenuItem itemDtSet = menu.add( 0, MENU_ITEM_DTSET, 0, R.string.menu_item_dt );
  MenuItem itemEnd = menu.add( 0, MENU_ITEM_END, 0, R.string.menu_item_end );
  itemAdd.setIcon( android.R.drawable.ic_menu_add );
  itemSet.setIcon( android.R.drawable.ic_menu_preferences );
  itemDtSet.setIcon( android.R.drawable.ic_menu_more );
  itemEnd.setIcon( android.R.drawable.ic_menu_close_clear_cancel );
  return true;
}

 onCreateOptionsMenuは、Menuオブジェクトを引数として受け取り、これに対してメニューを追加していきます。あとから参照できるようにMenuItemクラスの変数で追加したメニュー項目を記憶します。これはあとからアイコンをセットするために必要になるからです。やり方としては、後述するメニューのIDを使って、menuオブジェクトからメニュー項目のオブジェクト(MeunItem)を見つける方法もあるのですが、それも記述が少し面倒になるため、ここでは、ローカル変数を作っています。

 ここで、「MENU_ITEM_」で始まる定数は、以下のようにWorldClock.javaの55行目あたりで別途、定義してあります。

private static final int     MENU_ITEM_ADD = 0;
private static final int     MENU_ITEM_SET = 1;
private static final int     MENU_ITEM_DTSET = 2;
private static final int     MENU_ITEM_END = 99;

 コードで記述するやり方はそれほど難しくないため、項目数がそんなにないのならコードで定義してもいいのですが、このように別途IDを定義しなければなりません。このIDは、あとでどのメニュー項目が押されたのかを検出するために使います。こういうIDを定数として管理するのは結構面倒で、まちがって重複した値を定義してしまうこともあります。間違いをなくすには、今回のようにダイレクトに定義するのではなくて、ひとつ前の値に「+1」をするようなコードを使うという方法もあります。ですがxmlを使えば、何も定義する必要はなく、管理がより簡単になります。

 onCreateOptionsMenuでは、メニュー生成が成功したことを通知するためにtrueを返す必要があります。

メニューのアイコンはデフォルトのリソースを使用

 前述の画面を見ると、メニューの4エリアそれぞれにアイコンが表示されています。しかしリソースの「res/drawable-*」を見てもファイルとしては「ic_btn_search.png」しかありません。

 ここで参照されているアイコンは、すべてAndroid自身が持っているリソースを参照しているのです。これは、Android SDKのインストールフォルダにある「platforms」以下にあるフォルダに実際のデータが置かれており、これらに関しては、コード中で名前を指定するだけ(android.R.drawable.XXXX)で利用できます。

システム側で定義されているアイコンは、Android SDKの下のplatformsフォルダの下にある

 アプリケーションを実行するプラットフォームで図柄が違っています。たとえばAndroid 1.6の場合には「ic_menu_add」(android.R.drawable.ic_menu_add)は「platforms\android-4\data\res\drawable」にあります。ところがAndroid 2.1では「platforms\android-4\data\res」には「drawable-hdpi」「drawable-mdpi」「drawable-land-ldpi」の3つにic_menu_addが配置されています。これは解像度や画面の向きに応じて画像を自動的に切り替えることができるようにするためです。前記の名前で指定しておけば、実際の画面の表示密度に合わせて適当なものを選択してくれます。

 なお、こうしたシステム側のリソースを使うには、SDKのインストールフォルダで、APIレベルごとになっているdata/resフォルダを調べてファイル名を得たら、“android.R.”を付けてリソース参照を行ないます。Android自身が表示に使っている画像のすべてをアプリケーションから利用できるわけでなく、このresフォルダ以下にあるもののみです。

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン