Android 2.xでAndroid Compatibility Packageを使ってFragmentを動かしてみた

Android Developers Blog: Fragments For All

公式blogで発表があったとおり、Honeycomb以前のバージョンでもFragmentを使えるようにするライブラリが提供されたので試しに触ってみた。

以下、とりあえず動いたという程度でHoneycombでのFragmentについては勉強不足なので変な実装のところもあるかも…。

インストール

SDK Managerに"Android Compatibility Package"というのが追加になっているので、それにチェックを入れてインストール。

Compatibility_Package

開発プロジェクトへの適用

ANDROID_SDK/extras/android/compatibility/v4の下にandroid-support-v4.jarがあるので、これをEclipseの開発プロジェクトに適用する。

extras_jar

開発プロジェクトにlibsディレクトリを作ってその中へjarファイルを入れ、プロジェクトのビルド設定でandroid-support-v4.jarを参照する。

eclise_libs

ソースコード

基本的にはHoneycombでFragmentを使う場合と同じで良い。

ただし、このCompatibility PackageはFragmentなどのクラスのパッケージ名が”android.support.v4.app"になっていて、Honeycombでの"android.app"では無いことに注意。

またFragmentを適用するActivityは、Activityクラスを継承するのではなく、FragmentActivityクラスを継承する必要がある。理由はよく分からないしあまりググっても出てこないけれど、今まで通りのActivityを継承していると実行時にFramgmentが"ClassNotFoundException"となって動作しない。

とりあえず最低限のレイアウト、Fragmentの定義だけ行って動作させてみたソースを以下に。

fragment_ginger

LegacyFragmentSampleActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<span class="hljs-keyword">package</span> net.swingingblue.android.legacyfragmentsample;
 
<span class="hljs-keyword">import</span> android.os.Bundle;
<span class="hljs-keyword">import</span> android.support.v4.app.FragmentActivity;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LegacyFragmentSampleActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FragmentActivity</span> </span>{
    <span class="hljs-comment">/** Called when the activity is first created. */</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
 
        setContentView(R.layout.main);
    }
}

サンプルアプリの入り口となるActivity。

Activityの継承元をActivityではなくFragmentActivityにするのがポイント。HoneycombではActivityのままでOKなので、おそらく互換ライブラリを使った実装であることを明示的に指定する意味合いなのかもしれない。

res/layout/main.xml

1
2
3
4
5
6
7
8
9
10
<span class="hljs-meta"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name">LinearLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"fill_parent"</span>
    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"fill_parent"</span>
    ></span>
 <span class="hljs-tag"><<span class="hljs-name">fragment</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"net.swingingblue.android.legacyfragmentsample.TestFragment"</span>
            <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/test"</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">LinearLayout</span>></span>

LegacyFragmentSampleActivity#onCreateで読み込まれるレイアウト定義。

中はFragementタグのみで、Fragmentの実装クラスとしてTestFragmentを指定。

TestFragment.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<span class="hljs-keyword">package</span> net.swingingblue.android.legacyfragmentsample;
 
<span class="hljs-keyword">import</span> android.os.Bundle;
<span class="hljs-keyword">import</span> android.support.v4.app.Fragment;
<span class="hljs-keyword">import</span> android.view.LayoutInflater;
<span class="hljs-keyword">import</span> android.view.View;
<span class="hljs-keyword">import</span> android.view.ViewGroup;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestFragment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Fragment</span> </span>{
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> View <span class="hljs-title">onCreateView</span><span class="hljs-params">(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState)</span> </span>{
         
        <span class="hljs-comment">// fragmentのレイアウトを読み込み</span>
        <span class="hljs-keyword">return</span> inflater.inflate(R.layout.fragment, container, <span class="hljs-keyword">false</span>);
    }
 
}

Fragmentの実装。

ここでは最低限として、onCreateView()でfragment.xmlのレイアウト定義を読み込んでいる。

res/layout/fragment.xml

1
2
3
4
5
6
7
8
<span class="hljs-meta"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name">LinearLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>></span>
     
    <span class="hljs-tag"><<span class="hljs-name">EditText</span> <span class="hljs-attr">android:text</span>=<span class="hljs-string">"EditText"</span> <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/editText1"</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>></span><span class="hljs-tag"></<span class="hljs-name">EditText</span>></span>
 
<span class="hljs-tag"></<span class="hljs-name">LinearLayout</span>></span>

fragmentの中のレイアウト定義。

ここではサンプルとしてTextViewを1つ置いているだけ。特にここではFragment特有の記述は無い。

その他

上のソースをHoneycombのエミュレータで実行させても正常に動いた。

気になるのが、android-support-v4.jarという形で静的にライブラリを組み込んでいる点。FragmentなどのAPIがリビジョンアップなどで仕様変更になった場合に、android-support-v5,v6という形でjarを入れ替えつつ追随したりする必要が(Honeycomb、それ以降のバージョンと2.3.x以下の実装を一本化したいとき)出てくる可能性はあるのかな、というところ。

今回Googleから提供された互換ライブラリには、Fragmentを含めて以下のAPIが提供されている。

v4/android-support-v4.jar contains:
- Fragment API. New in API 11 (3.0 - Honeycomb). http://developer.android.com/reference/android/app/Fragment.html
- Loader API. New in API 11 (3.0 - Honeycomb). http://developer.android.com/reference/android/app/LoaderManager.html
- CursorAdapter / ResourceCursorAdapter / SimpleCursorAdapter. These are the API 11 versions.
- MenuCompat allows calling MenuItem.setShowAsAction which only exists on API 11.

Loader系もあるので非同期でのデータ読み込みの仕組みもHoneycombと実装を合わせられる。

参考サイト

Android compatibility Fragment API « DroidDudes

コメント

  1. […] 参照元:https://swingingblue.sakura.ne.jp/blog/archives/003373.html カテゴリー: android   作成者: admin パーマリンク […]

タイトルとURLをコピーしました