Android Developers Blog: Fragments For All
公式blogで発表があったとおり、Honeycomb以前のバージョンでもFragmentを使えるようにするライブラリが提供されたので試しに触ってみた。
以下、とりあえず動いたという程度でHoneycombでのFragmentについては勉強不足なので変な実装のところもあるかも…。
インストール
SDK Managerに"Android Compatibility Package"というのが追加になっているので、それにチェックを入れてインストール。
開発プロジェクトへの適用
ANDROID_SDK/extras/android/compatibility/v4の下にandroid-support-v4.jarがあるので、これをEclipseの開発プロジェクトに適用する。
開発プロジェクトにlibsディレクトリを作ってその中へjarファイルを入れ、プロジェクトのビルド設定でandroid-support-v4.jarを参照する。
ソースコード
基本的にはHoneycombでFragmentを使う場合と同じで良い。
ただし、このCompatibility PackageはFragmentなどのクラスのパッケージ名が”android.support.v4.app"になっていて、Honeycombでの"android.app"では無いことに注意。
またFragmentを適用するActivityは、Activityクラスを継承するのではなく、FragmentActivityクラスを継承する必要がある。理由はよく分からないしあまりググっても出てこないけれど、今まで通りのActivityを継承していると実行時にFramgmentが"ClassNotFoundException"となって動作しない。
とりあえず最低限のレイアウト、Fragmentの定義だけ行って動作させてみたソースを以下に。
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と実装を合わせられる。
コメント
[…] https://swingingblue.sakura.ne.jp/blog/archives/003373.html […]
[…] 参照元:https://swingingblue.sakura.ne.jp/blog/archives/003373.html カテゴリー: android 作成者: admin パーマリンク […]