Android 4.x時代のアプリにないと残念なActionBarとはAndroidで動く携帯Javaアプリ作成入門(41)(2/3 ページ)

» 2013年04月11日 18時00分 公開
[緒方聡イーフロー]

Compatibility packageを使わずに実装する

 ActionBarはAndroid 3.0(API Level 11)以上で使用可能な機能です。ただし、連載第25回「Compatibility packageで2.x系でもマルチサイズ対応」の「便利なFragmentsをAndroid 2.x系でも」で紹介したCompatibility packageを使用すれば、それよりも前のバージョンでも利用可能です。

 今回の記事では、簡単なサンプルのためにCompatibility packageは扱っていませんが、ADTのウィザードで生成したプロジェクトはCompatibility packageを使用したソースコードが出力されるようになっています。「Android 2.xのシェアは捨て置けないがActionBarも捨てがたい」ということであれば、導入を検討してみてください。

 Compatibility packageを使用しない場合は、プロジェクトが、Minimum Required SDKがAndroid 3.0以上、またはTarget SDKがAndroid 3.0以上になるように設定します。

図6 プロジェクト作成ウィザードの設定

 この条件が満たされていなければActionBarは使用できません。

 今回のサンプルのように、縦画面でActionBarを上下に分割したい場合は、AndroidManifest.xmlのactivity要素に以下の4行目のように「android:uiOption="splitActionBarWhenNarrow"」という属性を追加します。

<activity
    android:name="com.example.android.actionbar.MainActivity"
    android:label="@string/app_name"
    android:uiOptions="splitActionBarWhenNarrow" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

 ActionBarに表示するMenuItemが2つまでなら、上部のActionBarに表示されるため分割されません。3つ目から縦画面では表示されなくなります。分割した場合、5つまでなら表示され、6つ目から表示されなくなります。MenuItemを2つに抑える、または3つ目以降の使用頻度が低いなどの場合は分割しない、横画面専用にする、などの方針をアプリ設計時に行うようにしてください。

 この辺の動作は、本アプリの「Add item」ボタンを押すことで確認できます。縦横を切り替えながら確認してみてください。増えたMenuItemを削除するには、そのMenuItemをタップします。なおエミュレータで縦横を切り替えるのは、Windowsなら[Ctrl]+[F11]キーです。

アクションアイテムを表示する

 ActionBarは従来のメニューを置き換えるものである、と説明しました。ActionBarに並んでいるアイコンは、従来のメニューのMenuItemと同じものを使用します。以下は本サンプルの「menu.xml」の内容です。

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/action_edit"
        android:icon="@android:drawable/ic_menu_edit"
        android:showAsAction="ifRoom|withText"
        android:title="@string/action_edit"/>
    <item
        android:id="@+id/action_preview"
        android:icon="@android:drawable/ic_menu_view"
        android:showAsAction="ifRoom|withText"
        android:title="@string/action_preview"/>
    <item
        android:id="@+id/action_save"
        android:actionLayout="@layout/actionview_progress_bar"
        android:icon="@android:drawable/ic_menu_save"
        android:showAsAction="ifRoom|withText|collapseActionView"
        android:title="@string/action_save"/>
    <item
        android:id="@+id/action_settings"
        android:icon="@android:drawable/ic_menu_preferences"
        android:showAsAction="ifRoom|withText"
        android:title="@string/action_settings"/>
</menu>

 重要なのは、item要素の「android:showAsAction」という属性です。この属性を用いてActionBar上でメニューアイテムがどのように配置、表示されるかを指定できます。

意味
never 常に表示しない
ifRoom 表示する余裕があれば表示
always 常に表示
withText android:titleのテキストを表示。"|"を使用して他の値と同時に指定可能
collapseActionView android:actionViewLayoutで指定されているアクションビューと関連付ける。"|"を使用して他の値と同時に指定可能

 多くのケースで有効なのが「"ifRoom|withText"」です。表示されるアイコンを見て、機能が確実に推測できるのであればwithTextを省略するのも方法の1つです。alwaysは表示するスペースがなくても強制的に表示するため、使用する際に注意が必要です。

 今回のサンプルでは、説明のためにSearchViewのアクションアイテムにalwaysを指定しているため、以下のように強制表示され、SearchViewが押せなくなっています。

図7 アイコンが重なってしまった

ActionBarにプログレスバーを表示する

 本サンプルは、保存アイコンをタップするとActionBarにプログレスバーが表示され、進ちょくを表示するように実装してあります。以下の定義で着目すべき点は、3行目のandroid:actionLayout属性と5行目のandroid:showAsAction属性です。

    <item
        android:id="@+id/action_save"
        android:actionLayout="@layout/actionview_progress_bar"
        android:icon="@android:drawable/ic_menu_save"
        android:showAsAction="ifRoom|withText|collapseActionView"
        android:title="@string/action_save"/>

 android:showAsAction属性にはcollapseActionViewが指定してあります。これは、「アクションアイテムがタップされた際にActionBarに展開するのはandroid:actionLayoutで指定されたViewです」ということを指示するものです。

 もし指定しなければ、図8のようにプログレスバーが直接展開されてしまい、タップしてもアクションアイテムとしてイベント通知はされません。

図8 属性の指定を忘れると、このようになる

 android:actionLayout属性では、プログレスバーのレイアウトを指定しています。レイアウト定義ファイルの内容は以下の通り、特別な設定はありません。

<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/progressBar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

ActionBarの表示・非表示を動的に設定する

 場合によってはActionBarを表示したくない、そんなアプリもあるでしょう。写真、電子書籍、動画などのビューアーなどは、そうしたケースに当てはまります。特にActionBarを分割して表示している場合、かなりの表示領域が専有されてしまいます。

 その画面が独立したActivityであれば、AndroidManifest.xmlのActivity属性に静的に「android:theme="@android:style/Theme.Holo.NoActionBar"」という属性を記述することで実現可能です。今回のサンプルはFragmentで実装しているため、この方法は利用できません。

 動的に表示・非表示を切り替えるには、ActionBar#show()およびActionBar#hide()を呼び出します。ActionBar#hide()を呼び出すと、ユーザーはActionBarにまったくアクセスできなくなります(Menuがハードキーの端末なら、辛うじてオプションメニューは表示されますが)。ユーザーが直感的に分かるような操作で、ActionBarが再び表示されるようにしておくことをお勧めします。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。