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

package net.swingingblue.android.legacyfragmentsample;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class LegacyFragmentSampleActivity extends FragmentActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
    }
}

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

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

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 <fragment android:name="net.swingingblue.android.legacyfragmentsample.TestFragment"
            android:id="@+id/test"
            android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>

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

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

TestFragment.java

package net.swingingblue.android.legacyfragmentsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TestFragment extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		// fragmentのレイアウトを読み込み
		return inflater.inflate(R.layout.fragment, container, false);
	}

}

Fragmentの実装。

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

res/layout/fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent" android:layout_height="match_parent">
	
	<EditText android:text="EditText" android:id="@+id/editText1"
		android:layout_width="wrap_content" android:layout_height="wrap_content"></EditText>

</LinearLayout>

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

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