スポンサードリンク

Android 3.0(Honeycomb)から導入されたAction Barですが、Android 4.0(Ice Cream Sandwich、ICS)の実機がそろそろ出るとこともあり、そろそろ既存のアプリもAction Barに対応させて使ってみたい。

もちろんAndroid 2.3(Gingerbread)以前ではそのままでは、Action Barが使えないのですが・・・。
しかし、Android SDKのICSのサンプルとしてGingerbread以前でもAction Barのようなものが使えるものがあったので、これを使えばGingerbread以前の端末でもAction Barが使えるようになるようです。

それがActionBarCompat

とりあえず、どういうものか見るために、eclipseからこのサンプルソースコードを見ましょう。

まず、「新規」→「Android Sample Project」を選びます。

次に「Android 4.0」を選んで次へ

最後に「ActionBarCompat」を選んで完了すると、ソースコードがeclipseのworkspaceにコピーされます。

このサンプルはManifest.xmlに

1
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="14"/>

となっているとおり、Android 1.5(Cupcake)から使えます。



しかし、サンプルコードを見ても全体が良くわからない、既存のアプリの何処を改造すればできるのか、といった感じだったので、全体把握のためにクラス図を書いてみることにしました。
(なんせHoneycombのAction Barを使ったことないのですから・・・。)

とりあえず、8個のJavaファイルだから大したことないだろうとクラス図書いたらこんなことに・・・。(クリックしたら別画面に開きます)

もっと分かりやすく、全体把握に必要なところを抜き出すと、こんな感じ。

というわけで、クラス図を書いて分かったこと。
・実際の画面に表示されるActivityはMainActivityクラスであるが、ActionBarActivityクラスを継承している。
・このActionBarActivityクラスがActionBarHelperという抽象クラスのオブジェクトを持つことでCupcake~ICSバージョン間によるAndroidのActionBarを実装差を埋めてくれています。
(といっても、Cupcake~Gingerbreadまでは、OSにActionBarそのものの実装がありませんが。)

もう少し、ソースを読んでいると、
ActionBarHelperでは

1
2
3
4
5
6
7
8
9
public static ActionBarHelper createInstance(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        return new ActionBarHelperICS(activity);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        return new ActionBarHelperHoneycomb(activity);
    } else {
        return new ActionBarHelperBase(activity);
    }
}

となっていて、ActionBarを実装しているクラスをAPIバージョンによって変えています。
・Cupcake~Gingerbreadまでは「ActionBarHelperBase」クラス
・Honeycombでは「ActionBarHelperHoneycomb」クラス
・ICSでは「ActionBarHelperICS」クラス
このようにして、Androidのバージョン差を埋めているようです。



Cupcake~GingerbreadをActionBar対応するためのクラス「ActionBarHelperBase」クラスやそれに付随するクラス「SimpleMenu」「SimpleMenuItem」に関してはまだソースをじっくり読んでないのですが、HoneycombやICSのメニューと互換があるようにするためのメソッドのようにも見えます。処理がないメソッド等がありましたので・・・。

というわけで、既存のアプリをActionBarに対応させるには、
このサンプルのMainActivity.java”以外”をそのまま使えばよいようです。

ただし、当然ですがソースコード内のアイコンのリソース等はアプリに合わせて適宜変更が必要のようです。
例えば、ActionBarHelperBaseクラスに

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void setupActionBar() {
    final ViewGroup actionBarCompat = getActionBarCompat();
    if (actionBarCompat == null) {
        return;
    }
 
    LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(
            0, ViewGroup.LayoutParams.FILL_PARENT);
    springLayoutParams.weight = 1;
 
    // Add Home button
    SimpleMenu tempMenu = new SimpleMenu(mActivity);
    SimpleMenuItem homeItem = new SimpleMenuItem(
            tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));
    homeItem.setIcon(R.drawable.ic_home);
    addActionItemCompatFromMenuItem(homeItem);
 
    // Add title text
    TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);
    titleText.setLayoutParams(springLayoutParams);
    titleText.setText(mActivity.getTitle());
    actionBarCompat.addView(titleText);
}

となっていて、15行目のホームアイコンの設定のところとか。

今回はこのへんで・・・。
次回はMainActivity.javaを例にActionBarCompatの使い方を説明できたらいいなぁと思う。

スポンサードリンク