Skip to content

Most visited

Recently visited

navigation

メニュー

メニューは、さまざまなタイプのアプリケーションで共通するユーザー インターフェースです。使い慣れた一貫した操作感を提供するには、Menu API を使ってアクティビティでユーザーのアクションとその他のオプションを表示する必要があります。

Android 3.0(API レベル 11)からは、Android 搭載端末では専用の Menu ボタンを表示する必要はなくなりました。 この変更により、Android アプリでは従来の 6 アイテムのメニューパネルを使用するのをやめて、共通のユーザー アクションを表示するアプリバーを提供する必要があります。

一部のメニュー アイテムのデザインと操作感は変わりましたが、一連のアクションとオプションを定義する意味論は、引き続き Menu API に基づきます。 このガイドでは、すべてのバージョンの Android で表示されるメニューやアクションの基本的な 3 タイプを作成する方法について説明します。

オプション メニューとアプリバー
オプション メニューは、アクティビティの主なメニュー アイテムのコレクションです。 ここには、「検索」、「メールの作成」、「設定」のような、アプリにグローバルな影響があるアクションを配置する必要があります。

オプション メニューの作成のセクションをご覧ください。

コンテキスト メニューとコンテキスト アクション モード
コンテキスト メニューは、ユーザーが要素を長押しクリックするときに表示されるフローティング メニューです。 ここでは、選択したコンテンツやコンテキスト フレームに影響するアクションが提供されます。

コンテキスト アクション モードでは、画面最上部にあるバーで選択されたコンテンツに影響するアクション アイテムが表示され、ユーザーは複数のアイテムを選択できます。

コンテキスト メニューの作成のセクションをご覧ください。

ポップアップ メニュー
ポップアップ メニューでは、メニューを呼び出すビューに固定された縦方向のリストでアイテムが表示されます。 特定のコンテンツに関連するアクションの概要を表示したり、コマンドの 2 番目の部分のオプションを表示したりする場合に適しています。 ポップアップ メニューのアクションは対応するコンテンツに直接影響を与えないようにしてください(そのためにコンテキスト アクションがあります)。 ポップアップ メニューは、アクティビティのコンテンツ領域に関連する拡張されたアクション用です。

ポップアップ メニューの作成のセクションをご覧ください。

XML でのメニューの定義

Android では、すべてのメニュータイプに、メニュー アイテムを定義するための標準の XML 形式が提供されます。 アクティビティのコードでメニューをビルドするのではなく、メニューとそのすべてのアイテムを XML メニュー リソースで定義してください。 その際、アクティビティやフラグメントでメニュー リソースをインフレートできます(Menu オブジェクトとして読み込む)。

メニュー リソースを使うことは、次のような理由で優れた方法と言えます。

メニューを定義するには、プロジェクトの res/menu/ ディレクトリ内で XML ファイルを作成し、次の要素を含むメニューをビルドします。

<menu>
メニュー アイテムのコンテナである Menu を定義します。<menu> 要素は、ファイルのルートノードである必要があります。また、1 つ以上の <item><group> 要素を持つことができます。
<item>
メニューで 1 つのアイテムを表示する MenuItem を作成します。この要素には、サブメニューを作成するために、ネストされた <menu> 要素を含めることができます。
<group>
省略可能な <item> 要素の非表示コンテナ。メニュー アイテムでアクティブ状態や可視性のようなプロパティを共有できるよう、メニュー アイテムを分類できます。 詳細については、メニュー グループの作成のセクションをご覧ください。

game_menu.xml という名前のメニュー例を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

<item> 要素では、アイテムの概観と動作を定義するために使用できるいくつかの属性がサポートされています。 上記メニューのアイテムには、次の属性が含まれます。

android:id
ユーザーがアイテムを選択するときに、アプリケーションがそのアイテムを認識できるようにする、アイテム固有のリソース ID。
android:icon
アイテムのアイコンとして使用するための、ドローアブルへの参照。
android:title
アイテムのタイトルとして使用するための、文字列への参照。
android:showAsAction
このアイテムがアプリバーのアクション アイテムとして、いつ、どのように表示される必要があるのかを指定。

これらの属性は使用する必要のある最も重要なものですが、他にもさまざまな属性があります。サポートされているすべての属性については、メニュー リソースのドキュメントをご覧ください。

サブメニューを除くすべてのメニューで、<item> の子として <menu> 要素を追加すると、アイテムにサブメニューを追加できます。 PC アプリケーションのメニューバー(ファイル、編集、表示など)にあるアイテムのように、アプリケーションにトピックで分類できる多くの機能がある場合は、サブメニューが役立ちます。 次に例を示します。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>

アクティビティでメニューを使うには、MenuInflater.inflate() を使って、メニュー リソースをインフレートする(XML リソースをプログラム可能なオブジェクトに変換する)必要があります。 次のセクションでは、各メニュー アイテムのメニューをインフレートする方法を説明します。

オプション メニューの作成

図 1. Android 2.3 のブラウザでのオプション メニュー

オプション メニューでは、「検索」、「メールの作成」、「設定」のような、現在のアクティビティ コンテキストに関連するアクションとその他のオプションを含める必要があります。

オプション メニューのアイテムが画面上のどこに表示されるかは、開発対象のアプリケーションのバージョンによって異なります。

図 2. ナビゲーション タブ、カメラ アクション アイテム、アクション オーバーフロー ボタンが表示されている Honeycomb Gallery アプリのアプリバー。

Activity サブクラスや Fragment サブクラスのいずれかからオプション メニューのアイテムを宣言できます。 アクティビティとフラグメントの両方でオプション メニューのアイテムを宣言する場合、それらは UI に統合されます。 まず、アクティビティのアイテムが表示され、次にアクティビティに各フラグメントが追加される順序で各フラグメントのアイテムが表示されます。 必要に応じて、移動する必要のある各 <item>android:orderInCategory 属性を使ってメニュー アイテムの順序を並べ替えることができます。

アクティビティのオプション メニューを指定するには、onCreateOptionsMenu() をオーバーライドします(フラグメントは独自の onCreateOptionsMenu() コールバックを提供)。 このメソッドでは、メニュー リソース(XML で定義)をコールバックで提供される Menu にインフレートできます。 次に例を示します。

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

add() を使ってメニュー アイテムを追加し、MenuItem API でそのプロパティを修正するために、findItem() でアイテムを取得することもできます。

Android 2.3.x 以前向けにアプリケーションを開発した場合、ユーザーが初めてメニューを開いたときに、システムは onCreateOptionsMenu() を呼び出してオプション メニューを作成します。 Android 3.0 以降向けに開発した場合、アクティビティの開始時にシステムが onCreateOptionsMenu() を呼び出し、アプリバーにアイテムが表示されるようにします。

クリック イベントを処理する

ユーザーがオプション メニューからアイテムを選択すると(アプリバーのアクション アイテムを含む)、アクティビティの onOptionsItemSelected() メソッドが呼び出されます。 このメソッドでは、選択された MenuItem が渡されます。getItemId() を呼び出してアイテムを識別できます。これにより、メニュー アイテムに対して一意の ID (メニュー リソースで android:id 属性を使用して定義、または add() メソッドに指定した整数で定義された ID)が返されます。 この ID を既知のメニュー アイテムと突き合わせて適切なアクションを実行できます。 次に例を示します。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

メニュー アイテムを正常に処理する場合、true を返します。メニュー アイテムを処理しない場合は、onOptionsItemSelected() のスーパークラスの実装を呼び出す必要があります(デフォルトの実装では fause が返されます)。

アクティビティにフラグメントが含まれる場合は、システムはまずアクティビティに対して onOptionsItemSelected() を呼び出します。次に true が返されるまで、またはすべてのフラグメントが呼び出されるまで、各フラグメントが追加された順序で、各フラグメントに対してこのメソッドを呼び出します。

ヒント: Android 3.0 では、android:onClick 属性を使って、メニュー アイテムのクリック動作を XML で定義できるようになっています。 その属性値は、メニューを使ってアクティビティによって定義されるメソッド名である必要があります。 そのメソッドは、パブリックであり、1 つの MenuItem パラメータを使用できる必要があります。システムがこのメソッドを呼び出すと、選択したメニュー アイテムが渡されます。 詳細と例については、メニュー リソースのドキュメントをご覧ください。

ヒント: アプリケーションに複数のアクティビティが含まれていて、その一部で同じオプション メニューが提供されている場合、onCreateOptionsMenu()onOptionsItemSelected() メソッドのみを実装するアクティビティを作成することを検討します。 その後、同じオプション メニューを共有する必要のある各アクティビティのこのクラスを拡張します。 この方法で、メニューの動作を継承するメニュー アクションとそれぞれの子クラスを処理するためのコードを 1 セットで管理できます。子孫アクティビティの 1 つにメニュー アイテムを追加する場合は、そのアクティビティの onCreateOptionsMenu() をオーバーライドします。 元のメニュー アイテムが作成されるように、super.onCreateOptionsMenu(menu) を呼び出し、menu.add() で新しいメニュー アイテムを追加します。 各メニュー アイテムのスーパークラスの行動をオーバーライドすることもできます。

実行時におけるメニュー アイテムの変更

システムが onCreateOptionsMenu() を呼び出した後、入力する Menu のインスタンスは残り、何らかの理由でメニューが無効にならない限り、onCreateOptionsMenu() をもう一度呼び出すことはありません。 ただし、初期のメニュー状態を作成し、アクティビティのライフサイクル中に変更しないという目的の場合に限って、onCreateOptionsMenu() を使用する必要があります。

アクティビティのライフサイクル中に発生するイベントに基づいてオプション メニューを変更する場合は、onPrepareOptionsMenu() メソッドで変更ができます。 このメソッドは、現在存在している Menu オブジェクトを渡し、それを編集(アイテムの追加、削除、無効化など)できるようにします (フラグメントでも onPrepareOptionsMenu() コールバックが提供されます)。

Android 2.3.x 以前では、ユーザーが [Menu] ボタンを押してオプション メニューを開くたびに、システムによって {@linkandroid.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} が呼び出されます。

Android 3.0 以降では、メニュー アイテムがアプリバーに表示されるときに、オプション メニューは常に開かれているとみなされます。 イベントが発生し、メニューをアップデートするときは、invalidateOptionsMenu() を呼び出して、システムが onPrepareOptionsMenu() を呼び出すようリクエストする必要があります。

注: 現在フォーカスされている View に基づいてオプション メニューでアイテムを変更しないでください。 タッチモードの場合(ユーザーがトラックボールやリモコンの矢印ボタンを使うとき)、ビューはフォーカスを取得できないため、オプション メニューのアイテム変更のベースとしてフォーカスを使用しないでください。 View に状況依存のメニュー アイテムを提供する場合は、コンテキスト メニューを使います。

コンテキスト メニューの作成

図 3. フローティング コンテキスト メニュー(左)とコンテキスト アクションバー(右)のスクリーンショット。

コンテキスト メニューでは、UI の特定のアイテムやコンテキスト フレームに影響するアクションが提供されます。どのビューにもコンテキスト メニューを使用できますが、大半は ListViewGridView など、各アイテムでユーザーが直接実行できるビュー コレクションのアイテムに使用されます。

コンテキスト アクションを提供するには次の 2 つの方法があります。

注: コンテキスト アクション モードは、Android 3.0(API レベル 11)以降で使用可能で、使用可能な場合にコンテキスト アクションを表示するのに適した方法です。 アプリで 3.0 以前のバージョンをサポートする場合、その端末ではフローティング コンテキスト メニューを使う必要があります。

フローティング コンテキスト メニューの作成

フローティング コンテキスト メニューを提供するには:

  1. registerForContextMenu() を呼び出し、View を渡して、コンテキスト メニューに関連付ける必要のある View を登録します。

    アクティビティで ListViewGridView が使用され、各アイテムに同じコンテキスト メニューを提供する場合、ListViewGridViewregisterForContextMenu() に渡してコンテキスト メニューにすべてのアイテムを登録します。

  2. ActivityFragmentonCreateContextMenu() メソッドを実装します。

    登録されたビューが長押しクリック イベントを受け取ると、システムは onCreateContextMenu() メソッドを呼び出します。 通常、ここでメニュー リソースをインフレートして、メニュー アイテムを定義します。次に例を示します。

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

    MenuInflater では、メニュー リソースからコンテキスト メニューをインフレートできます。そのコールバック メソッド パラメータには、ユーザーが選択した View と選択されたアイテムに関する追加情報を提供する ContextMenu.ContextMenuInfo オブジェクトが含まれます。 アクティビティに、それぞれ別のコンテキスト メニューを提供する複数のビューがある場合、これらのパラメータを使ってインフレートするコンテキスト メニューを決定できます。

  3. onContextItemSelected() を実装します。

    ユーザーがメニュー アイテムを選択すると、システムによってこのメソッドが呼び出され、適切なアクションを実行できるようになります。 次に例を示します。

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
            case R.id.edit:
                editNote(info.id);
                return true;
            case R.id.delete:
                deleteNote(info.id);
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }
    

    getItemId() メソッドは、選択されたメニュー アイテムの ID を照会します。XML でメニューを定義するのセクションで説明されているように、android:id 属性を使って XML で各メニュー アイテムを割り当てる必要があります。

    メニュー アイテムを正常に処理する場合、true を返します。メニュー アイテムを処理しない場合は、スーパークラスの実装にメニュー アイテムを渡す必要があります。 アクティビティにフラグメントが含まれる場合、そのアクティビティは最初にこのコールバックを受け取ります。 未処理のときにスーパークラスを呼び出すと、システムは truefalse が返されるまで、各フラグメントのそれぞれのコールバック メソッドに 1 つずつ、各フラグメントが追加された順序でイベントを渡します。 (Activityandroid.app.Fragment のデフォルトの実装では false が返されるため、未処理のときは常にスーパークラスを呼び出す必要があります)

コンテキスト アクション モードの使用

コンテキスト アクション モードは、ActionMode のシステム実装で、ユーザーによるコンテキスト アクション実行のための操作に焦点が置かれています。 ユーザーがアイテムを選択してこのモードを有効にすると、画面の最上部にコンテキスト アクションバーが表示され、現在選択中のアイテムで実行できるアクションが表示されます。 このモードが有効な間は、ユーザーは複数のアイテムを選択したり(許可されている場合)、アイテムを選択解除したり、アクティビティ内を移動し続けたり(許可されている範囲内で)することができます。 ユーザーがすべてのアイテムの選択を解除したり、Back ボタンをしたり、またはバーの左端で Done アクションを選択したりすると、このアクション モードは無効になり、コンテキスト アクションバーは表示されなくなります。

注: コンテキスト アクションバーをアプリバーと関連付ける必要はありません。 コンテキスト アクションバーの表示が、アプリバーの位置にかかる場合でも、個別に操作できます。

コンテキスト アクションを提供するビューでは、通常は次の 2 つのイベントのいずれかまたは両方で、コンテキスト アクションを呼び出す必要があります。

アプリケーションがどのようにコンテキスト アクション モードを呼び出して各アクションの動作を定義するかは、デザインによって異なります。 基本的に次の 2 つのデザインがあります。

次のセクションでは、各シナリオに必要な設定について説明します。

個別のビューに対してコンテキスト アクション モードを有効にする

ユーザーが特定のビューを選択するときにのみ、コンテキスト アクション モードを呼び出すには、次のことを行う必要があります。

  1. ActionMode.Callback インターフェースを実装します。このコールバック メソッドでは、コンテキスト アクションバーに対してアクションを指定して、アクション アイテムでのイベント クリックに応答し、アクション モードのその他のライフサイクル イベントを処理できます。
  2. ユーザーがビューを長押しクリックしたときなど、バーを表示するときに、startActionMode() を呼び出します。

次に例を示します。

  1. ActionMode.Callback インターフェースを実装します。
    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
    
        // Called when the action mode is created; startActionMode() was called
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate a menu resource providing context menu items
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
            return true;
        }
    
        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false; // Return false if nothing is done
        }
    
        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.menu_share:
                    shareCurrentItem();
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
            }
        }
    
        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    };
    

    これらのイベント コールバックは、それぞれでもイベントに関連する ActionMode オブジェクトを渡すこと以外は、オプション メニューのコールバックとほぼ同じです。ActionMode API を使って、setTitle()setSubtitle()(選択されているアイテム数を表示するのに役立つ)でタイトルとサブタイトルを変更するなど、CAB にさまざまな変更を行うことができます。

    また、上記のサンプルでは、アクション モードが破棄されるときに mActionMode 変数が null に設定されます。 次のステップでは、それがどのように初期化され、アクティビティやフラグメントでどのようにメンバー変数を保存するのが役立つかについて説明します。

  2. startActionMode() を呼び出して、View で長押しクリックに応答するときなど、適切な時にコンテキスト アクション モードを有効にします。

    someView.setOnLongClickListener(new View.OnLongClickListener() {
        // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (mActionMode != null) {
                return false;
            }
    
            // Start the CAB using the ActionMode.Callback defined above
            mActionMode = getActivity().startActionMode(mActionModeCallback);
            view.setSelected(true);
            return true;
        }
    });
    

    startActionMode() を呼び出すと、システムは作成された ActionMode を返します。 メンバー変数でこれを保存すると、その他のイベントに応じてコンテキスト アクションバーを変更できます。 上記の例では、ActionMode を使って、ActionMode インスタンスがアクティブな状態である場合に、アクション モードを開始する前にメンバーが null であるかどうかを確認して、そのインスタンスが再作成されないようにしています。

バッチ コンテキスト アクションを ListView または GridView で有効にする

ListViewGridView(または AbsListView の別の拡張)にアイテムのコレクションがあり、ユーザーがバッチ アクションを実行できるようにする場合は、次のことを行う必要があります。

次に例を示します。

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {
        // Here you can do something when items are selected/de-selected,
        // such as update the title in the CAB
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        // Respond to clicks on the actions in the CAB
        switch (item.getItemId()) {
            case R.id.menu_delete:
                deleteSelectedItems();
                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate the menu for the CAB
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context, menu);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        // Here you can make any necessary updates to the activity when
        // the CAB is removed. By default, selected items are deselected/unchecked.
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        // Here you can perform updates to the CAB due to
        // an invalidate() request
        return false;
    }
});

これだけです。これで、ユーザーが長押しクリックでアイテムを選択すると、システムは onCreateActionMode() メソッドを呼び出して、特定のアクションでコンテキスト アクションバーを表示するようになります。 コンテキスト アクションバーが表示されている間は、追加のアイテムを選択できます。

コンテキスト アクションによって一般的なアクション アイテムが提供されるとき、ユーザーが長押しクリックの動作に気付かない可能性があることを考慮して、アイテムを選択できるようにチェックボックスや同様の UI 要素を追加したい場合もあります。 ユーザーがチェックボックスをオンにするとき、setItemChecked() でオンにされた状態にそれぞれのリストアイテムを設定して、コンテキスト アクション モードを呼び出すことができます。

ポップアップ メニューの作成

図 4. 右上のオーバーフローボタンに固定された Gmail アプリのポップアップ メニュー。

PopupMenuView に固定されるモーダル メニューです。スペースがある場合にはアンカービューの下に、スペースがない場合はビューの上に表示されます。 次の場合に役立ちます。

注: PopupMenu は API レベル 11 以降で使用できます。

XML でメニューを定義する場合の、ポップアップ メニューの表示方法について、次に示します。

  1. コンストラクタを使って PopupMenu のインスタンスを作成します。これにより、メニューを固定する必要のある、現在のアプリケーションの ContextView が取得されます。
  2. MenuInflater を使って、PopupMenu.getMenu() によって返される Menu オブジェクトにメニュー リソースをインフレートします。
  3. PopupMenu.show() を呼び出します。

ポップアップ メニューを表示する android:onClick 属性を含むボタンの一例を以下に示します。

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_overflow_holo_dark"
    android:contentDescription="@string/descr_overflow_button"
    android:onClick="showPopup" />

アクティビティでは、次のようにポップアップ メニューが表示されます。

public void showPopup(View v) {
    PopupMenu popup = new PopupMenu(this, v);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.actions, popup.getMenu());
    popup.show();
}

API レベル 14 以降では、PopupMenu.inflate() でメニューをインフレートする 2 行を組み合わせることができます。

ユーザーがアイテムを選択するか、メニュー領域外をタップすると、メニューが閉じます。 PopupMenu.OnDismissListener を使って dismiss イベントをリッスンできます。

クリック イベントを処理する

ユーザーがアイテム メニューを選択したときにアクションを実行するには、PopupMenu.OnMenuItemClickListener インターフェースを実装し、setOnMenuItemclickListener() を呼び出して PopupMenu でそれを登録する必要があります。 ユーザーがアイテムを選択すると、インターフェースで onMenuItemClick() コールバックが呼び出されます。

次に例を示します。

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

メニュー グループの作成

メニュー グループは、特定の特徴を共有するメニュー アイテムのコレクションです。グループを使って次のことを実行できます。

メニュー リソースの <group> 要素内で <item> 要素をネストするか、add() メソッドでグループ ID を指定して、グループを作成できます。

グループを含むメニュー リソースの一例を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

グループ内のアイテムは、最初のアイテムと同じレベルで表示されます(メニューの 3 つのアイテムすべてが兄弟)。 ただし、グループ ID を参照するか、上記のメソッドを使って、グループ内の 2 つのアイテムの特徴を変更できます。 システムが、グループ化されたアイテムを分けることもありません。 たとえば、各アイテムに android:showAsAction="ifRoom" を宣言する場合、その両方がアクションバーまたはアクション オーバーフローに表示されます。

オンにできるメニュー アイテムの使用

図 5.オンにできるアイテムを含むサブメニューのスクリーンショット。

メニューは、オプションのオンとオフを切り替えるインターフェースとして役立ちます。スタンドアロンのオプションにはチェックボックスを、相互に排他的なオプションのグループにはラジオボタンを使います。 図 5 に、ラジオボタン付きのオンにできるアイテムを含むサブメニューを示します。

注: アイコン メニューのメニュー アイテム(オプション メニューから)ではチェックボックスやラジオボタンを表示できません。 アイコン メニューのアイテムをオンにできるようにする場合、状態が変わるごとにアイコンやテキストを入れ替えて、オンにされた状態を手動で示す必要があります。

個々のメニュー アイテムには <item> 要素の android:checkable 属性を、グループ全体には <group> 要素の android:checkableBehavior 属性を使って、オンにする際の動作を定義できます。 たとえば、このメニュー グループのすべてのアイテムはラジオボタンでオンにできます。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

android:checkableBehavior 属性には、次のいずれかを指定できます。

single
グループから 1 つのアイテムのみをオンにできる(ラジオボタン)
all
すべてのアイテムをオンにできる(チェックボックス)
none
どのアイテムもオンにできない

<item> 要素の android:checked 属性を使うと、アイテムをデフォルトでオンになった状態にすることができ、setChecked() メソッドを使うと、その状態をコード内で変更できます。

オンにできるアイテムが選択されると、システムは onOptionsItemSelected() のような、それぞれの item-selected コールバック メソッドを呼び出します。 チェックボックスやラジオボタンによって自動的にその状態が変わることはないため、ここでチェックボックスの状態を設定する必要があります。 isChecked() で、アイテムの現在の状態(ユーザーが選択する前の状態)を照会できます。その後、setChecked() でオンにされた状態を設定します。 次に例を示します。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

この方法でオンにされた状態を設定しない場合には、アイテム(チェックボックスまたはラジオボタン)の表示状態はユーザーがオンにしたときに変更されません。 状態を設定すると、アクティビティはアイテムのオンにされた状態を維持して、ユーザーが後でメニューを開いたときに、開発者が設定したオンにされた状態が表示されるようになります。

注: オンにできるメニュー アイテムは、セッション単位ベースのみでの使用を意図したもので、アプリケーションが破棄された後は、保存されません。 ユーザー用に保存するアプリケーション設定がある場合は、共有のプリファレンスを使ってデータを保存してください。

インテントに基づくメニュー アイテムの追加

Intent を使ってメニュー アイテムでアクティビティが起動されるようにしたい場合もあります(自分のアプリケーションのアクティビティであるか、別のアプリケーションのアクティビティであるかにかかわらず)。 使用するインテントがわかっていて、インテントを開始する必要のある特定のメニュー アイテムがある場合は、アイテムが選択された時に呼び出される適切なコールバック メソッド(onOptionsItemSelected() コールバックのような)中に、startActivity() でインテントを実行できます。

ただし、ユーザーの端末にインテントを処理するアプリケーションが含まれているかどうかが不明な場合、それを呼び出すメニュー アイテムを追加すると、そのインテントによってアクティビティが解決されないためにメニュー アイテムが機能しなくなることがあります。 これを解決するために、Android では、インテントを処理する端末で Android によってアクティビティが検出されるときに、メニュー アイテムがメニューに動的に追加されるようにします。

インテントを受け入れる使用可能なアクティビティに基づいてメニュー アイテムを追加するには:

  1. CATEGORY_ALTERNATIVECATEGORY_SELECTED_ALTERNATIVE カテゴリでインテントを定義します。その他の要件も必要です。
  2. {@linkandroid.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) Menu.addIntentOptions()} を呼び出します。その際、Android によって、インテントを実行できるアプリケーションが検索され、メニューにそのアプリケーションが追加されます。

インテントを満たすアプリケーションがインストールされていない場合、メニュー アイテムは追加されません。

注: CATEGORY_SELECTED_ALTERNATIVE は、現在画面で選択されている要素の処理に使われます。 これは、{@linkandroid.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) onCreateContextMenu()} でメニューを作成するときにのみ使用する必要があります。

次に例を示します。

@Override
public boolean onCreateOptionsMenu(Menu menu){
    super.onCreateOptionsMenu(menu);

    // Create an Intent that describes the requirements to fulfill, to be included
    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering applications.
    menu.addIntentOptions(
         R.id.intent_group,  // Menu group to which new items will be added
         0,      // Unique item ID (none)
         0,      // Order for the items (none)
         this.getComponentName(),   // The current activity name
         null,   // Specific items to place first (none)
         intent, // Intent created above that describes our requirements
         0,      // Additional flags to control items (none)
         null);  // Array of MenuItems that correlate to specific items (none)

    return true;
}

定義されたインテントに一致するインテント フィルタが提供されていることを見つけた各アクティビティに対して、メニュー アイテムのタイトルにインテント フィルタの android:label の値を、メニュー アイテムのアイコンにアプリケーション アイコンを使って、メニュー アイテムが追加されます。 addIntentOptions() メソッドによって、追加されたメニュー アイテム数が返されます。

注: {@linkandroid.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()} を呼び出すとき、最初の引数で指定されたメニュー グループによって、すべてのメニュー アイテムがオーバーライドされます。

アクティビティを他のメニューに追加できるようにする

他のアプリケーションにアクティビティのサービスを提供して、アプリケーションを他のメニューに含めることができるようにすることもできます(前述の役割を逆にする)。

他のアプリケーションのメニューに含まれるようにするには、通常どおりインテント フィルタを定義する必要がありますが、インテント フィルタのカテゴリに、CATEGORY_ALTERNATIVECATEGORY_SELECTED_ALTERNATIVE 値を含めるようにしてください。 次に例を示します。

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

インテント フィルタの記述の詳細については、インテントとインテント フィルタをご覧ください。

この方法を使ったサンプル アプリケーションについては、Note Pad のサンプルコードをご覧ください。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)