2012/06/18

ActionBarCompatをライブラリ化して自分のアプリに組み込んでみる

[2012年6月29日追記] Google IO 2012でActionBarの互換ライブラリがリリースされる予定だとの発表がありました。 この内容を利用する前に、公式の互換ライブラリがリリースされていないかご確認下さい。

自作アプリケーションからActionBarを使おうとした場合には、API Level 11(Android 3.0)以降でないと対応していません。 不特定多数に配布するアプリケーションの作成する際には、普通はAndroid 1.6か2.1以降、どんなに悪くても2.3以降の対応として、まだAPI Level 11以降のみをターゲットにしたアプリケーションを作成する機会は少ないのではないでしょうか。

Android 3.0以前に対応したActionBarの実装について検索をすると、SDK以下のsamples/android-15/ActionBarCompat/にAPI Level 4(Android 1.6)以降に対応したActionBar互換アプリケーションがある事がわかります。

最初はioschedアプリもActionBarのような動きをするので参考にしようとしたのですが、面倒になったので改めて探してctionBarCompatアプリに辿りついたのでした。

このアプリケーションを全面的にコピーする方法は試されているようでしたが、 便利そうだったので、これからいくつかのプロジェクトで使う機会もあるだろうと思ったので、ライブラリとして自分のアプリケーションから参照を追加するようにしました。

作業環境

基本的にはv4サポートライブラリを使って、Android 2.3端末のAcer Liquid MTの実機で確認していきます。

Android 3.2(Honeycomb)環境としては、Acer Iconia Tab A500を使って確認します。

Android 4.0(ICE)環境は、Xperia Mini Proを入手しようとしていますが、いまのところはエミュレーターで行ないます。

ActionBarCompatをライブラリ化する流れ

作業ステップはおおまかに次のようになります。

  • ActionBarCompatサンプルから、自分のworkspace以下に新しいプロジェクトを作成
  • プロジェクトのパッケージ名を変更
  • srcフォルダのパッケージ名をプロジェクトのパッケージ名に変更
  • MainActivityなどの不要なファイルを削除
  • (android.support.v4.app.Fragmentを使う場合のみ) ActionBarActivityクラスをFragmentActivityのサブクラスに
  • プロジェクトのプロパティからAndroid欄の"is library"にチェックをつけライブラリプロジェクトに変更
  • 自作のアプリケーションのプロパティからライブラリに追加
  • 自作アプリケーションのActivityをActionBarActivityのサブクラスに変更
  • 自作アプリケーションに見栄えに合せたActionBarの背景色などの変更

The ActionBar Result Image

ActionBarCompatサンプルから、自分のworkspace以下に新しいプロジェクトを作成

新規プロジェクトの作成する時にはオプションの中からCreate project from existing sampleを選択すると、サンプルプロジェクトのコピーをデフォルトのworkspace以下に作成する事ができます。

ActionBarCompatサンプルはAPI Level 15 (Android 4.0.3)を選択すると表示されます。

プロジェクトのパッケージ名を変更

このままではパッケージ名がcom.exampleeから始まってしまうので、自分のドメインに変更してしまいます。

この作業は、まずプロジェクトフォルダを右クリックして、Android Toolsの中にある"Rename Application Package"メニューを選択して行ないます。

この時に、次のステップにあるsrcフォルダの中にあるパッケージ名を先に変更してしまうとEclipseが競合を解決できなくなるので注意してください。

srcフォルダのパッケージ名をプロジェクトのパッケージ名に変更

おなじみのsrcフォルダ直下にあるパッケージフォルダを右クリックして"Refactor"から"Rename"を選択します。

この時入力するパッケージ名は先ほど行なったApplication Packageの名前と同じにしておきます。

MainActivityなどの不要なファイルを削除

この時点でMainActivityを選択して実行すると、サンプルを動かすことができるはずです。 問題なくビルドできているプロジェクトをライブラリプロジェクトにしていきます。

resフォルダの中にあるlayout/main.xml, menu/main.xmlは不要なので削除しておくか、自作アプリケーションのプロジェクトに移動するなどして、ActionBarCompat以下には配置しないようにします。

また2つのmain.xmlとMainActivity.javaを削除すると、values/strings.xmlの内容もほとんど不要になります。

values/strings.xmlからapp_nameを残して、他のエントリを削除します。

(android.support.v4.app.Fragmentを使う場合のみ) ActionBarActivityクラスをFragmentActivityのサブクラスに

互換パッケージのFragmentを使う場合には、ActivityのサブクラスからはFragmentManagerのインスタンスにアクセスできないので、FragmentActivityを使用します。

この場合には、ActionBarActivityクラスの親クラスをActivityからandroid.support.v4.app.FragmentActivityに変更します。

あるいはActionBarActivityクラスファイルをコピーして、ActionBarFragmentActivityのようなクラス名にした上で、FragmentActivityの子クラスとしてもいいかもしれません。

将来的にActivityとFragmentActivityを使い分ける事があるのなら、こちらの方がお勧めです。

ActionBarActivity変更個所の抜粋

public abstract class ActionBarActivity extends FragmentActivity {
    final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
プロジェクトのプロパティからAndroid欄の"is Library"にチェックをつけライブラリプロジェクトに変更

ここまで作業を進めて、エラーがなければライブラリにして、他のプロジェクトから参照できるようにします。

is Libraryをセットした画面キャプチャ

自作のアプリケーションのプロパティからライブラリに追加

ここまできて、自作アプリケーションのプロジェクトフォルダに移動します。

プロパティから参照するライブラリにActionBarCompatを指定します。

Libraryを追加した画面キャプチャ

自作アプリケーションのActivityをActionBarActivityのサブクラスに変更

extends Activityextends FragmentActivityと書かれているところを、extends ActionBarActivityに変更します。

ActionBarCompatのvalues/menu/main.xmlを参考にして、通常のmenuリソースを作成して、ActionBarActivityのサブクラスでonCreateOptionsMenu(Menu)メソッドでメニューを構成します。

ここでndroid:showAsAction="always"が指定されたメニューはActionBarにアイコンが表示されます。 "never"を指定すれば、別途メニュー(Android 3.0以降ならContext Menu)に文字とアイコン付きで表示されます。

Menuの作成方法については、これぐらいの点を気にすれば、他は特に変わった点はありません。

自作アプリケーションに見栄えに合せたActionBarの背景色などの変更

メニューの作成方法は通常通りですが、この時点ではまだ、ActionBarらしくはみえません。 ここからさらに必要な作業をまとめると次のような項目があります。

  • 自作アプリケーションのAndroidManifest.xmlのMainActivityに ユニークなStyle名を設定
  • 自作アプリケーションのresフォルダに、values/styles.xmlを作成
  • ActionBarCompatプロジェクトからvalues-v11, values-v13フォルダを自作アプリケーションのresフォルダにコピー

カスタマイズの方法について

ここではタイトルバーの色と文字色を変更するまでの流れをまとめておきます。

テーマの有効化

まずはAndroidManifest.xmlに、ActionBarCompatのAppThemeとは違う名前のテーマを設定します。

@style/JPAppThemeを指定した例

<activity
  android:name=".MainActivity"
  android:label="@string/app_name"
  android:theme="@style/JPAppTheme" >
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

この変更をすると、全体が白色ベースのThemeに変更され、ActionBarも太く、それらしく表示されるはずです。

ActionBarの背景色と文字色を変更する

変更には、全体をコピーするのではなく、ActionBarCompatで定義されている@style/AppThemeをparentとして差分を指定して、必要な個所だけを変更するようにします。

まずタイトル文字色を指定するリソースをvalues/colors.xmlに定義します。

values/colors.xml全体

<resources>
    <color name="jpactionbar_title_color">#efefef</color>
</resources>

次にAndroid 1.6〜2.3のアプリケーション用に背景色と文字色を変更します。

values/styles.xmlファイル全体

<resources>
    <style name="JPAppTheme" parent="@style/AppTheme">
        <item name="android:windowTitleBackgroundStyle">@style/JPActionBarCompat</item>
        <item name="actionbarCompatTitleStyle">@style/JPActionBarCompatTitle</item>
        <item name="android:textColor">@color/jpactionbar_title_color</item>
    </style>
    <style name="JPActionBarCompat" parent="@style/ActionBarCompat">
        <item name="android:background">#283255</item>
        <item name="android:textColor">@color/jpactionbar_title_color</item>
    </style>
    <style name="JPActionBarCompatTitle" parent="style/ActionBarCompatTitleBase">
        <item name="android:textColor">@color/jpactionbar_title_color</item>
    </style>
</resources>

ActionBarCompatのサンプルでは、parentにTheme.Lightを指定したいたので、色については白色地に黒色が基本になっています。

AndroidManifest.xmlで指定したThemeについては、parentを@style/AppThemeから継承するか、他のandroid:styleのThemeから継承するかはケース毎に違うと思います。

android:styleのThemeをparentに指定する場合には、ActionBarCompatのstyles.xmlを参考にしてください。

続いてvalues-v11/styles.xmlを編集します。

values-v11/styles.xmlファイル全体

<resources>
    <style name="JPAppTheme" parent="@style/AppTheme">
        <item name="android:actionBarStyle">@style/JPActionBar</item>
        <item name="android:textColor">@color/jpactionbar_title_color</item>
    </style>
    <style name="JPActionBar" parent="@style/ActionBar">
        <item name="android:background">#283255</item>
        <item name="android:textColor">@color/jpactionbar_title_color</item>
        <item name="android:titleTextStyle">@style/ActionBarTitle</item>
        <item name="android:icon">@drawable/icon</item>
    </style>
</resources>

こちらもvalues/styles.xmlと同じです。文字色を変更する指定が追加されています。

最後にvalues-v13/styles.xmlを編集します。 values-v11との差分だけを定義するので、内容は1項目だけです。

values-v11/styles.xmlファイル全体

<resources>
    <style name="JPActionBarTitle" parent="@style/ActionBarTitle">
        <item name="android:textColor">@color/jpactionbar_title_color</item>
    </style>
</resources>

これぐらいを指定すると、だいたいどのバージョンの端末でも正しく表示されると思いますが、 API Versionによってボタンの配色など、違うところがあるので、TextViewやButton用にStyleを定義するといった事は必要だと思います。

さいごに

細かい際を全て吸収するのは難しいですが、ActionBar自体はAndroid 2.3とAndroid 3.2の端末で同じようにみえています。

ViewPagerと組み合せて使っていますが、v4サポートのFragmentと組み合せて、 できるだけ快適な操作性を提供していきたいと思っています。

これまで郵便番号検索と、Exif情報を編集するExifPMアプリを作ってきましたが、郵便番号の方はFragment対応を進めていて、ActionBarを組み込む予定です。

0 件のコメント: