minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

Android は、以下の3種類のメニューを提供しています。

Options Menu

Activity に対するメニューアイテムのセットです。
これは [MENU] キーを押すことで表示されます。
メニューアイテムは、以下の2種類に分けられます。

Context Menu

(右クリックで開くような)いわゆるポップアップメニューです。
モバイルアプリケーションの場合は、ビューをタッチしたときなどに出すメニューのことです。

Submenu

Options Menu か Context Menu の子として作成されるサブメニューです。
サブメニューの下にさらにサブメニューを作ることは出来ません。

Options Menu

前述したように、[MENU] キーを押すことで表示されるメニューです。

options_menu.png

初期表示時には最大6つまでしかメニューアイテムを表示できません。
"More" を選択することによって、より多くのアイテムを使うことができます。

ここにはアプリケーションの基本的な機能をアイテムとして置くべきでしょう。
トピックが多岐に渡る場合は、サブメニューを使ってアイテムをグループ化することもできます。

[MENU] キーが押されると、Activity.onCreateOptionsMenu() が呼ばれます。
このメソッドをオーバーライドすることで、メニューを実装することができます。

リソース定義

res/menu/options_menu.xml に、Options Menu 用のリソースを作成します。

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:title="New Game" />
    <item android:id="@+id/quit"
          android:title="Quit" />
</menu>

Java 側では、以下のようにします。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    return true;
}

これで Options メニューが実装されました。
実行すると、以下のようになります。[MENU] キーは F2 や PageUp に割り当てられています。

options_menu1.png

メニューアイテム選択時の実装

Activity.onOptionsItemSelected() をオーバーライドします。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.new_game:
        //newGame();
        return true;
    case R.id.quit:
        finish();
        return true;
    }
    return false;
}

動的なメニューアイテムの変更

Activity.onPrepareOptionsMenu() をオーバーライドすることで、メニューアイテムを
動的に変更することができます。
このメソッドはメニューを開く度に毎回呼ばれます。

private int count = 0;
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem item = menu.findItem(R.id.new_game);
    String baseTitle = getResources().getString(R.string.baseMenuTitle);
    ++count;
    item.setTitle(new String(baseTitle + " : " + count));
    return true;
}

しかし、動的に Options Menu を変更することは Bad Practice になり得ます。
※ ユーザに混乱を与える可能性がある

Context Menu

ポップアップメニューです。
Options Menu は Activity に対するメニュー、
こちらは View に対するメニュー、といったところです。

メニューのリソース定義は、Options Menu と同じです。

res/menu/context_menu1.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:title="Start" android:id="@+id/item01"></item>
  <item android:title="Line" android:id="@+id/item02"></item>
  <item android:title="Draw" android:id="@+id/item03"></item>
</menu>

異なるのは、実装方法です。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    ListView view = (ListView)findViewById(R.id.ListView01);
    view.setAdapter(new SampleListAdapter(this));
    registerForContextMenu(view);
}

このように、Activity,onCrete() 内で予め registerForContextMenu() で View を登録しておく必要があります。
ここで登録した View 内で Context Menu が発生するようなイベントが発生すると
onCreateContextMenu() 内に処理が移ります。
今回の例は ListView です。この場合はリストアイテムを1秒以上タッチするとイベントが発生します。

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context_menu1, menu);
}

ここで、動的に Context Menu を生成します。

context_menu1.png

こんな感じになります。
メニューアイテムを選択したときの処理は、Activity に記述します。

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.item01:
        // selected item1
        break;
    case R.id.item02:
        // selected item2
        break;
    case R.id.item03:
        // selected item3
        break;
    default:
        return super.onContextItemSelected(item);
    }
    return true;
}

Submenu

Submenu の実装は簡単です。

<item android:id="@+id/new_game" android:title="@string/baseMenuTitle">
  <menu>
    <item android:id="@+id/item01" android:title="Tetris"></item>
    <item android:title="Raiden" android:id="@+id/item02"></item>
  </menu>
</item>

このように、XML ファイルに定義するだけです。
もちろん、動的にも作成できます。

Menu Item Intent

メニューアイテムに Intent を設定することができます。
こうすると、アイテムを選択したときに別の Activity を起動させることができます。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    MenuItem item = menu.findItem(R.id.sample);
    item.setIntent(new Intent(this, SampleActivity.class));
    return true;
}

上の例では、sample というIDを持ったメニューアイテムに対して
SampleActivity の Intent を設定しています。
これで、Options Menu から sample アイテムを選択すれば
SampleActivity が起動します。
元に戻る場合は、[戻る] キーを押します。デフォルトでは Esacpe キーです。