妄想プログラマのらくがき帳 : 7月 2013

2013年7月28日日曜日

[Android]オプションメニューを表示する。その2。

Android3.0以降ではハードキーの無い機種が存在します。そのような機種の場合、オプションメニューの表示位置は画面下部ではなく、アクションバー右端のアイコン(Action Overflow)押下時のリストになります。

Action Overflowを押下すると、メニューがリストとなって表示されます。

また、メニューxmlのitemタグにshowAsAction属性を指定することで、アクションバーへの表示方法を変更することができます。showAsAction属性の値は以下の通りです。
ifRoomアクションバーに空きがあれば項目をアクションバーに表示する
withTextアクションバーに空きがあればアイコンと共にandroid:titleで指定した文字列を表示する
neverアクションバーに表示しない(常にAction Overflowでの表示とする)
always常にアクションバーに表示する(アクションバーに空きが無い場合、他のUI要素に重なった状態で表示される)
collapseActionViewActionViewを折りたたみ可能にする

例として次のようなメニューを定義します。
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/menu1" android:titleCondensed="m1" android:title="menu1" android:icon="@drawable/menu_icon" android:showAsAction="ifRoom|withText" />
    <item android:id="@+id/menu2" android:title="menu2" android:titleCondensed="m2" />
</menu>
これがどんなふうに表示されるかというと・・・

このようにandroid:showAsAction="ifRoom|withText"を指定したmenu1はアクションバーに表示され、指定していないmenu2はAction Overflowに格納されます。menu1はwithTextを設定していますが、画面幅が小さいためアイコンのみの表示になっています。

2013年7月16日火曜日

[Android]オプションメニューを表示する。その1。

オプションメニューとは、メニューボタンを押下したときに画面下部に出てくるメニューです(※ハードキーのメニューボタンが無い機種の場合、画面下部ではなくアクションバーのAction Overflowによって表示されます)。

メニューを表示するには、まずxmlファイルでメニューを定義します。
Eclipseのメニュー「ファイル」-「新規」-「その他」から「Android XML ファイル」を選択します。


次の画面では、リソースタイプを「Menu」にし、ファイル名を入力します。


完了すると、プロジェクトの「res」-「menu」フォルダにxmlファイルが生成されるので、ここにメニューを定義します。
以下がメニューxmlの例です。
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/menu1" android:titleCondensed="m1" android:title="menu1" android:icon="@drawable/menu_icon">
        <menu>
            <item android:id="@+id/menu1_1" android:titleCondensed="m1_1" android:title="Menu1_1"/>
            <item android:id="@+id/menu1_2" android:titleCondensed="m1_2" android:title="Menu1_2"/>
        </menu>
    </item>
    <item android:id="@+id/menu2" android:title="menu2" android:titleCondensed="m2" android:icon="@drawable/menu_icon">
        <menu>
            <group android:id="@+id/menu2_g1" android:checkableBehavior="all">
                <item android:id="@+id/menu2_g1_1" android:title="Menu2_g1_1"/>
                <item android:id="@+id/menu2_g1_2" android:title="Menu2_g1_2"/>
            </group>
            <group android:id="@+id/menu2_g2">
                <item android:id="@+id/menu2_g2_1" android:title="Menu2_g2_1"/>
            </group>
        </menu>
    </item>
</menu>
menuタグの中にitemタグでメニューの項目を定義します。menuタグは入れ子にすることができ、入れ子にされたmenuはサブメニューになります。また複数の項目をgroupタグで囲うことでグループ化できます。グループ化すると、複数の項目を同時に非表示にする等の操作が簡単になります。

itemタグの主な属性は以下の通りです。
title項目の表示文字列
titleCondensed項目の省略表示文字列。表示する際にtitleに設定した文字列だと長すぎる場合、こちらが表示される。
icon項目のアイコン
showAsActionアクションバーでの表示方法
checkabletrueなら項目にチェックボックスを表示する
orderInCategorygroup内での項目並び順

今回は上記xml例で定義したメニューをAndroid2.3で表示してみます。
まず、オプションメニューを表示するActivityのonCreateOptionsMenu()をオーバーライドします。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.option_menu_sample, menu);
    return true;
}
MenuInflater.inflate()の第1引数に表示するメニューを定義したメニューリソースを指定します(上記コードの場合、option_menu_sample.xmlに定義したメニューを表示します)。

次に、メニュー項目を選択されたときの動作を定義します。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu1_1:
            Toast.makeText(this,
                "Menu1_1 selected.", Toast.LENGTH_SHORT).show();
            return true;
        case R.id.menu2_g1_1:
        case R.id.menu2_g1_2:
            // チェックボックスは自前でチェック状態を反転させる必要あり
            if (item.isChecked()) {
                item.setChecked(false);
            }
            else {
                item.setChecked(true);
            }
            return true;
        default:
            // メニュー選択イベントをハンドリングしないときは、
            // superクラスのonOptionsItemSelected()を呼び出す。
            return super.onOptionsItemSelected(item);
    }
}
上記のようにActivityのonOptionsItemSelected()をオーバーライドし、選択項目に応じた処理を記述します。
MenuItem.getItemId()で選択項目のIDが取得できるので、それをswitchのキーにします。
上記の例では、menu1_1を選択されたときにToastを表示し、menu2_g1_1、menu2_g1_2を選択されたときはチェックボックスの状態をトグルしています。また、コメントにも書いていますが、選択イベントをハンドリングしないときはsuper.onOptionsItemSelected()を呼び出すようにします。

上記のオプションメニューを表示させると以下のようになります。

一番左がメニューボタンを押下したときの表示、真ん中がmenu1を選択したときの表示、右がmenu2を選択したときの表示です。このようにサブメニューは親の項目を選択したときにポップアップで表示されます。
ちなみにアイコンは自作の適当アイコンです(´ー`A;)実際のアプリでは項目を表した適切な画像を使いましょう。