スワイプ動作でページ送りする(ViewPager)
|ViewPagerを使うとページ送りを簡単に実装することが出来ます。
ViewPagerは左右にページ送りできます。またアニメーションがつくので非常にわかりやすく、直感的なUIを提供できる機能です。
便利な機能ですが、2011/9/29時点ではAndroid SDKに含まれておらず、Android Compatibility package, revision 3(外部ライブラリー)として提供されています。
今回は、この外部ライブラリーの追加から実際のサンプルコードが動作するまでを紹介します。ポイントは次の2点です。
- 外部ライブラリ「Android Compatibility package, revision 3」の導入
- ViewPagerをつかうためにはPagerAdapterが必要
ごく簡単に言えば、ViewPagerは入れ物です。表示する内容(ギャラリーアプリであれば写真、動画など)はPagerAdapter経由でViewPagerに指示することになります。
それでは、外部ライブラリの導入からソースコードの解説まで順番に確認していきましょう。
外部ライブラリの導入
「Android Compatibility package, revision 3」はAndroid SDKおよびADVマネージャーからインストールできます。
コンパチビリティパッケージは fragmentの紹介記事 “Compatibility Package を使って、FragmentをHoneyComb以外で利用する”でもインストール方法を紹介しています(こちらはMac)。
Available packages一覧からダウンロードしてください。成功するとInstalled packagesに「Android Compatibility package, revision 3」が表示されます。
ダウンロードした外部ライブラリは以下に格納されています。
android-sdk-windows/extras/android/compatibility/
compatibilityディレクトリ以下にはv4(Android3.2未満)およびv13(Android3.2以降)と、環境にあわせてディレクトリが用意されています。プロジェクトにのターゲットAPIに応じて配置してください。
プロジェクトへのコピー例
- プロジェクトのルート以下にlibsディレクトリを作成
- android-sdk-windows/extras/android/compatibility/v4/
- プロジェクトのルート/libs/android-support-v4.jarをコピー
(v4を利用する場合。Android 3.2以降はv13で読み替えてください)
compatibilityディレクトリ以下にREADME/NOTICEテキストが用意されています。注意点、機能などが紹介されていますので、読んでみると良いかもしれません。
Eclipseでの設定
続いてダウンロードした外部ライブラリをプロジェクトへ追加しましょう。
Eclipseで追加したいプロジェクトを開いてください。プロジェクトのプロパティで設定できます。
手順は以下の通りです。
Eclipseメニュー>プロジェクト>プロパティ
Javaのビルド・パス>ライブラリタブを選択>「外部Jar追加」ボタン
先ほどコピーしたjarファイルを選択
メニュー>プロジェクト>プロパティ (プロジェクト・エクスプローラから該当プロジェクトを右クリック、プロパティでも可)を選択して、プロパティ画面を開きます。プロパティ画面では、右ペインからJavaのビルド・パスを選択、ライブラリタブから外部Jarを追加してください。
ViewPagerを使う
ViewPagerはページ送りを簡単に実現できるコンポーネント(クラス)です。Viewという名前がついていますが、レイアウトファイル(xmlでの定義からの生成)やViewコンテナ(LinerLayout)なども利用できます。
ViewPagerを使う際の作法として、Viewの切り替え操作用にPagerAdapterを実装する必要があります。
まずはじめに、レイアウトファイルにViewPagerを配置して、ソースコードから参照可能な状態にしておきましょう。
■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" > <android.support.v4.view.ViewPager android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/viewpager"/> </LinearLayout>
レイアウトファイルmain.xmlの7行目でViewPager要素を記述、R.id.viewpagerを割り当てます。
ViewPagerの設定
ソースコードは以下の通りです。
■src/ViewPagerActivity.java
private Context mContext; private MyPagerAdapter mPagerAdapter; private ViewPager mViewPager; …省略… @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContext = this; mPagerAdapter = new MyPagerAdapter(); mViewPager = (ViewPager) findViewById(R.id.viewpager); mViewPager.setAdapter(mPagerAdapter); }
onCreateメソッド内11行目、PagerAdapterを継承してMyPagerAdapterを作成します。
13行目、作成したアダプタをViewPagerに設定して準備完了です。
ViewPagerは指を動かした際、アニメーションする際など、イベントごとにPagerAdapterを呼び出します。
PagerAdapterにはそれらイベントをトリガに、、画面に表示したいViewやViewコンテナ、レイアウトファイルを生成/破棄する役割があります。
PagerAdapterの作成
外部ライブラリということで、javadocが標準状態では効かないなど、リファレンスを見る機会が少ないため、
サンプルコードのコメントは多めにしてあります。詳しい挙動についてはコメントを参照しながら確認してください。
メソッド名 | 説明 |
---|---|
getCountメソッド | 表示するView(またはコンテナ)の総数 |
instantiateItemメソッド | ページの生成を行う |
destroyItemメソッド | ページの破棄を行う。instantiateItemメソッドとペア。 |
isViewFromObjectメソッド | ページを構成するViewの判定 |
■src/ViewPagerActivity.java
private static int NUM_OF_VIEWS = 5; private static int[] mViewColor = {Color.RED, Color.BLACK, Color.BLUE, Color.GREEN, Color.DKGRAY}; private class MyPagerAdapter extends PagerAdapter{ @Override public int getCount() { //Pagerに登録したビューの数を返却。サンプルは固定なのでNUM_OF_VIEWS return NUM_OF_VIEWS; } /** * ページを生成する * position番目のViewを生成し返却するために利用 * @param container: 表示するViewのコンテナ * @param position : インスタンス生成位置 * @return ページを格納しているコンテナを返却すること。サンプルのようにViewである必要は無い。 */ @Override public Object instantiateItem(View collection, int position) { TextView tv = new TextView(mContext); tv.setText("Hello, world! myPostion :" + position); tv.setTextColor(Color.WHITE); tv.setTextSize(30); tv.setBackgroundColor(mViewColor[position]); ((ViewPager) collection).addView(tv,0); return tv; } ...省略... } }
まず、Viewを表示するinstantiateItemメソッドの実装です。このメソッドでページ送りの際に表示する画面を作成します。
サンプルでは、27行目のように現在位置(ページの位置情報)を元に、Viewの背景色を変えています。
PagerAdapterクラスdestroyItemメソッドの実装
生成の次は破棄するdestroyItemメソッドです。
■src/ViewPagerActivity.java
private class MyPagerAdapter extends PagerAdapter{ ...省略... /** * ページを破棄する。 * postion番目のViweを削除するために利用 * @param container: 削除するViewのコンテナ * @param position : インスタンス削除位置 * @param object : instantiateItemメソッドで返却したオブジェクト */ @Override public void destroyItem(View collection, int position, Object view) { //ViewPagerに登録していたTextViewを削除する ((ViewPager) collection).removeView((TextView) view); } ...省略...
destroyItemメソッドは第2引数にinstantiateItemメソッドで生成したViewのオブジェクトが引き渡される特徴があります。
サンプルコードのdestroyItemメソッドでは単純にTextViewを生成しているため削除は(ViewPagerクラスの親クラスの)ViewGroupクラスのremoveViewメソッドを実行しています。
表示しているモノが簡単なView以外の場合もうすこし複雑になるはずです。
また破棄する情報などがあればdestroyItemメソッドで一緒に行えばいいでしょう。
PagerAdapterクラスisViewFromObjectメソッドの実装
ここまででほとんど実装は完了していますが、
最後にフォーカスや表示の調整のためにViewPagerから頻繁に呼び出されるisViewFromObjectについても紹介しておきます。
■src/ViewPagerActivity.java
private class MyPagerAdapter extends PagerAdapter{ ...省略... @Override public boolean isViewFromObject(View view, Object object) { //表示するViewがコンテナに含まれているか判定する(表示処理のため) //objecthainstantiateItemメソッドで返却したオブジェクト。 //今回はTextViewなので以下の通りオブジェクト比較 return view==((TextView)object); } ...省略...
isViewFromObjectメソッドでは第2引数のobjectに第1引数のviewが含まれているか、判定する必要があります。
8行目のように簡単な判定文になることは稀で、実際はコンテナに入っているViewを取り出して個別に比較する処理がいります。
(スワイプ中のページ送りのフォーカスや表示調整に使ってると推測しています。きっちりやった方がいいでしょう)
以上、お疲れ様でした!