3.x未満で ActionBarを実現するには SDKにサンプルとして含まれている ActionBarCompatを使うか、サードパーティ製のライブラリを使うのが今までの定石…だったと思う。
が、Android 4.3に対応する APIと共に更新された Support Library Rev.18にはずばり ActionBarという代物が含まれている。
ActionBarCompatを格上げしただけな気がしないでもないけど、正式にライブラリとして公開されたのは大きい。
Support7Demosを動かして確認し、自アプリに組み込んでみた。
- Support Libraryに含まれる android-support-v7-appcompatプロジェクトをインポート(Android Project Existing Code)し、対象となるアプリが依存するライブラリとして設定。*1
- FragmentActivityを継承して作っていた Activityを ActionBarActivityを継承するように変更。*2
- AndroidManifest.xmlにて ActionBarActivityの派生アクティビティのテーマとして「Theme.AppCompat」を設定する。*3 (android:theme=”@style/Theme.AppCompat”)
とりあえず、以上でそれっぽい表示にはなる。*4
これだけだと本当にアクションバーが表示されるだけなのでメニューとかアイコンにアクションを割り当てるとかその辺りを積めてゆく必要がある。
次に今まで android.app.ActionBarを使っていた部分を android.support.v7.app.ActionBarを使うように変更。
- 「import android.app.ActionBar;」を「import android.support.v7.app.ActionBar;」に変更。
- 「Activity.getActionBar()」を「ActionBarActivity.getSupportActionBar()」に変更。
- Build.VERSION.SDK_INTを見て ActionBar関係を殺していた部分を生かすように。
メニューリソースに「android:showAsAction=”ifRoom|withText”」等記述してもアクションバーに表示してくれず、コードで書くか、記述を変える必要がある。
- コードで書く場合。
Activity/Fragment.onCreateOptionsMenuにて、「MenuItemCompat.setShowAsAction(menu.findItem(R.id.XXXX),MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);」ってな記述を。 - 記述を変える場合。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
app:showAsAction="ifRoom|withText" />
</menu>
結果、ActionBarActivityから無視されていた showAsActionプロパティが有効になると。
ただし、app:showAsActionはネイティブのアクションバーからは認識されない。
メニューリソースを共有するためには app:showAsActionと android:showAsAction両方書けばいい気もするけど、aapt.exeが落ちる羽目に。
共有するのなら showAsActionはコードで書くしかないようだ。
自分のアプリはお世辞にも ActionBarを活用しているとは言えない状態なので、これで対応作業は終了。
逆に 2.xx用のアプリでもアクションバーが使えるようになったのでこれから活用してゆくことになるかな。
今回、アクションバーに表示するメニューについて気になった点を一つ。
groupを作って複数の選択肢から選ばせるようなメニュー*5 作った場合の表示の違い。
- Android 4.1にて android.app.ActionBarを使用。
- Android 4.1にて android.support.v7.app.ActionBarを使用。
- Android 2.3にて android.support.v7.app.ActionBarを使用。
見ての通り、Android 4.1にて android.support.v7.app.ActionBarを使用した場合だけチェックボックスのアイコンが使われてて変。
こういうことが起こると言うことは、ネイティブの ActionBarが使える環境でも単純なラッパーになっているわけでは無いのかしら?
後でもうちっと調べてみるとしよう。
2013/11/01解決 詳しくは追記を。
2013/08/06追記
この辺りが関係するのかしら? : Issue 57990: android:checkableBehavior=”single” not working properly on ActionBarCompat released today 24-july
ソースを眺めてみると二つ目のコメントに該当するコードがどこかはすぐにわかるのだけど、android-support-v7-appcompat.jarを作り直すことになるので確認はかなり面倒そうだ。
2013/08/30追記
2.xxで ActionBarにサブメニューを含むメニューを表示したときにもサブメニューが開かないことが多々。
オーバーフローメニューにいる分には問題ない。
2013/09/17追記
サブメニューが開かない問題が発生するのは Activityでサブメニューを定義しており、setHasOptionsMenu(true)を呼んでいる Fragmentが一度でも登録されると以後はサブメニューが開かないという現象っぽく。
とりあえずは該当 Fragmentは setHasOptionsMenu(true)を呼んではいる物の実際はメニューをもっていなかったので setHasOptionsMenu(true)の呼び出し自体を削除して回避。
根本的なところは何も解決していないのは問題。
2013/11/01追記
groupを作って複数の選択肢から選ばせるようなメニューにてラジオボタンアイコンではなくチェックボックスアイコンが使われてしまうのは Support Library R19にて修正されているのを確認。
2014/02/10追記
アクションバーの背景やテキスト色をカスタマイズするのに TextAppearance.AppCompat.Widget等使うことになるけど、Light系は一部しか用意されていないのが面倒。
*1 android-support-v7-appcompat自身が android-support-v4.jar,android-support-v7-appcompat.jarを含んでいるので、他のライブラリ/アプリケーションのプロジェクトに含まれているのなら調整が必要。
*2 ActionBarActivityは FragmentActivityの派生クラスなので基本的にはそのまま動作する。
*3 個別にやらなくても applicationタグでまとめて設定しても大丈夫)
*4 ただし、テーマを設定していることからわかるとおり、アプリ内でテーマを切り替えていたりすると個別に対応してゆく必要がある。
*5 android:checkableBehavior=”single”なグループを作った場合ね。