Android Tips #31 ViewPager で Fragment を使う
はじめに
前回は ViewPager の基本的な使いかたについて解説しました。この ViewPager ですが、 View だけでなく Fragment をアイテムにすることができます! ということで今回は Support Package に用意されている FragmentPagerAdapter の使いかたを解説します。今回はサンプルは、下図のような伝統色Viewerをつくってみます。今回ももちろん Android 1.6 から動作します!
FragmentPagerAdapter を使って ViewPager をつくる
FragmentPagerAdapter は Fragment をアイテムとして表示する PagerAdapter です。各ページを Fragment にできます。このクラスを使って ViewPager を作ってみましょう。
1. Fragment をつくる
まずは ViewPager に表示するページの Fragment をつくります。Fragment には下記の情報が渡される想定です。
- ページ番号
- 伝統色名
- 伝統色名の由来
- 色タグ
レイアウトはこんな感じです。
fragment_traditional_color.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#cc0000" > <TextView android:id="@+id/name_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:textSize="30sp" android:textStyle="bold" android:layout_alignParentTop="true" /> <TextView android:id="@+id/text_view" android:layout_width="500dp" android:layout_height="wrap_content" android:layout_below="@+id/name_view" android:layout_marginLeft="20dp" android:textSize="20sp" /> <TextView android:id="@+id/color_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:textSize="80sp" android:textStyle="bold" android:textColor="#55ffffff" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" /> <TextView android:id="@+id/page_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginBottom="10dp" android:textSize="24sp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" /> </RelativeLayout>
あとは Fragment をつくります。Android 1.6 から対応させたい場合は android.support.v4.app.Fragment を必ず継承するようにしましょう。
TraditionalColorFragment.java
package jp.classmethod.android.sample.fragmentpager; import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import jp.classmethod.android.sample.traditionalcolorviewer.R; /** * 色情報を表示する Fragment. */ public class TraditionalColorFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // データを取得 Bundle bundle = getArguments(); int page = bundle.getInt("page"); String color = bundle.getString("color"); String name = bundle.getString("name"); String description = bundle.getString("description"); // View をつくる View layout = inflater.inflate(R.layout.fragment_traditional_color, container, false); layout.setBackgroundColor(Color.parseColor(color)); // 色名 TextView nameView = (TextView) layout.findViewById(R.id.name_view); nameView.setText(name); // 説明 (色名の由来) TextView textView = (TextView) layout.findViewById(R.id.text_view); textView.setText(description); // 色コード TextView colorView = (TextView) layout.findViewById(R.id.color_view); colorView.setText(color); // ページ TextView pageView = (TextView) layout.findViewById(R.id.page_view); pageView.setText(String.valueOf(page)); return layout; } }
ちなみに、以下のメソッドを使うと「#FF0000」のような String 文字列を色指定に使う int 型に変換できます。
int color = Color.parseColor(colorString);
2. FragmentPagerAdapter をつくる
次に FragmentPagerAdapter を継承したカスタムクラスをつくっていきます。 基本的な使いかたは PagerAdapter とあまり変わりませんが instantiateItem() は使わずに getItem() メソッド内で Fragment をつくります。 Fragment に値を渡すには setArguments() を使って Bundle で渡します。
TraditionalColorPagerAdapter.java
package jp.classmethod.android.sample.fragmentpager; import java.util.ArrayList; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.util.SparseArrayCompat; /** * 色情報の表示を管理する {@link FragmentPagerAdapter}. */ public class TraditionalColorPagerAdapter extends FragmentPagerAdapter { /** 色情報リスト. */ private ArrayList<SparseArrayCompat<String>> mList; /** * コンストラクタ. * @param fm {@link FragmentManager} */ public TraditionalColorPagerAdapter(FragmentManager fm) { super(fm); mList = new ArrayList<SparseArrayCompat<String>>(); } @Override public Fragment getItem(int position) { // 対象ページの色情報を取得 SparseArrayCompat<String> item = mList.get(position); // 色情報を Bundle にする Bundle bundle = new Bundle(); bundle.putInt("page", position); bundle.putString("color", item.get(0)); bundle.putString("name", item.get(1)); bundle.putString("description", item.get(2)); // Fragment をつくり Bundle をセットする TraditionalColorFragment frag = new TraditionalColorFragment(); frag.setArguments(bundle); return frag; } @Override public int getCount() { return mList.size(); } /** * 色情報を追加する. * @param item 色情報 */ public void add(SparseArrayCompat<String> item) { mList.add(item); } /** * 色情報をリストで追加する. * @param list 色情報リスト */ public void addAll(ArrayList<SparseArrayCompat<String>> list) { mList.addAll(list); } }
ちなみに、ここで使用している SparseArrayCompat は HashMap の代わりに使うことができる SparseArray の Support Package 版です。Android 1.6 (APIレベル4) から使うことができます!
3. FragmentActivity をつくる
最後に FragmentActivity を継承した Activity をつくります。FragmentPagerAdapter のコンストラクタ引数には FragmentManager を渡す必要があります。FragmentActivity#getSupportFragmentManager() で取得して渡します。
TraditionalColorActivity.java
package jp.classmethod.android.sample.fragmentpager; import java.util.ArrayList; import jp.classmethod.android.sample.traditionalcolorviewer.R; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.util.SparseArrayCompat; import android.support.v4.view.ViewPager; /** * 伝統色の情報を表示する {@link FragmentActivity}. */ public class TraditionalColorActivity extends FragmentActivity { /** 色情報を表示する {@link ViewPager}. */ private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // レイアウトをつくる setContentView(R.layout.activity_traditional_color); mViewPager = (ViewPager) findViewById(R.id.view_pager); // PagerAdapter をつくる FragmentManager fm = getSupportFragmentManager(); TraditionalColorPagerAdapter adapter = new TraditionalColorPagerAdapter(fm); adapter.addAll(getColorList()); // ViewPager にセットする mViewPager.setAdapter(adapter); } /** * 色情報リストを返す. * @return 色情報リスト */ private ArrayList<SparseArrayCompat<String>> getColorList() { ArrayList<SparseArrayCompat<String>> list = new ArrayList<SparseArrayCompat<String>>(); SparseArrayCompat<String> color1 = new SparseArrayCompat<String>(); color1.append(0, "#727171"); color1.append(1, "鈍色 (にびいろ)"); color1.append(2, "かすかに緑や茶の色味を持つグレイに近い色。"); SparseArrayCompat<String> color2 = new SparseArrayCompat<String>(); color2.append(0, "#2792c3"); color2.append(1, "縹 (はなだ)"); color2.append(2, "藍の単一染めの純正な青色。「花田」とも書く。"); SparseArrayCompat<String> color3 = new SparseArrayCompat<String>(); color3.append(0, "#917347"); color3.append(1, "朽葉色 (くちばいろ)"); color3.append(2, "朽ちた落ち葉の色に似た褐色の、黄橙色(「黄唐茶」)。「朽葉四十八色」と言う言葉がある。"); SparseArrayCompat<String> color4 = new SparseArrayCompat<String>(); color4.append(0, "#3a5b52"); color4.append(1, "虫襖 (むしあお)"); color4.append(2, "玉虫の羽根の色に見るような、暗い青みの緑。「虫青」とも書く。"); SparseArrayCompat<String> color5 = new SparseArrayCompat<String>(); color5.append(0, "#f8b500"); color5.append(1, "山吹色 (やまぶきいろ)"); color5.append(2, "山吹の花の色のような、冴えた赤味の黄色。「黄金色」とも言う。"); SparseArrayCompat<String> color6 = new SparseArrayCompat<String>(); color6.append(0, "#e5abbe"); color6.append(1, "石竹色 (せきちくいろ)"); color6.append(2, "ナデシコ科の植物セキチクの花のような淡い赤色。"); SparseArrayCompat<String> color7 = new SparseArrayCompat<String>(); color7.append(0, "#e60026"); color7.append(1, "紅蓮 (ぐれん)"); color7.append(2, "盛んに燃え上がる炎の色。「紅蓮地獄(寒さのために皮膚が裂け血が流れ、紅の蓮の花のようになる)」を「紅の炎の燃え立つ所」と誤認したのが由来。"); SparseArrayCompat<String> color8 = new SparseArrayCompat<String>(); color8.append(0, "#007b43"); color8.append(1, "常磐色 (ときわいろ)"); color8.append(2, "スギなどの常緑樹の葉のようなくすんだ緑色。"); list.add(color1); list.add(color2); list.add(color3); list.add(color4); list.add(color5); list.add(color6); list.add(color7); list.add(color8); return list; } }
以上で完成です!!実行してみましょう♪
今回のサンプルでは 8 つの伝統色を登録してみました。さて、何の色でしょう?
ソースコード
今回も github にソースコードを公開しました。ぜひ参考にしてください!
suwa-yuki/TraditionalColorViewer
まとめ
前回の ViewPager の基本的な使いかたに続いて、今回は Fragment でつくる方法を解説しました。 公式リファレンスには「Fragment を使うほうがケースとして多い」と書かれているように ViewPager を使うケースとしては View より Fragment を使うほうが多いと思うので、ぜひ参考にしていただければと思います!