スワイプで画面を横に切り替える ViewPager の利用方法
この資料ではスワイプ操作で横方向に画面を切り替える UI を実装する方法を紹介します。
スワイプ操作による横方向の画面切り替えは、主にスクリーンマップ内の同レベルの情報ナビゲーションに利用することが一般的です。
例えば、Google Play ではホーム画面から、"APPS" や "GAMES" といった一段階下のレベルに移動した後は、横方向のスワイプナビゲーションが大いに活用されています。
例えば "APPS" では "HOME"、"TOP PAID"、"TOP FREE"・・・などが横方向に並べられ、それぞれが縦方向のリストとして情報閲覧できるようになっています。
Android の開発者サイトでも、スクリーンマップ内の兄弟関係のブラウズにはベストプラクティスとして Lateral Navigation (横方向ナビゲーション) が推奨されています。
スワイプ操作で画面を横に移動する ViewPager の利用
ここでは次のようなプログラムを作成します。
画面上方にページのタイトルが表示される領域があります。
画面を左方向にスワイプすると、画面が左側に移動し、次の画面が右側から現れます。
タイトルバーも、画面の内部も次の画面(ページ)に切り替わりました。
この動きはアンドロイドサポートパッケージ (Android Support Package) の ViewPager で利用可能です。 具体的には Support Package リビジョン 12 (2013年2月リリース) で v4 サポートライブラリに追加されています。
ViewPager の実装
では実装方法を見てみましょう。
まず準備として単純な Fragment を用意しましょう。ここでは3ページ切り替えることを考えているので、Fragement0, 1, 2 の三つ作ります。
ダミー画面なので書くまでも無いですが、一応コードを示すと次の通りです。
package com.example.viewpagertest1.fragment;
import com.example.viewpagertest1.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment0 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment0, null);
}
}
レイアウト (res/layout/fragment0.xml) は次の通りです。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 0"
android:textSize="30sp"
android:padding="50dp"/>
</LinearLayout>
とりあえず、こういう画面 (Fragment) を三つ用意しておきます。
さて、ポイントはここからです。
メイン画面 (アクティビティ) のレイアウトには次のように ViewPager と PagerTitleStrip を配置します。
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTitleStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#CCCCCC"
android:textColor="#000000"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
</android.support.v4.view.ViewPager>
この ViewPager に FragmentStatePagerAdapter を設定します。ListView にもデータアダプターを渡したように、 このページャーにはフラグメントを引き渡すアダプターを作る、というわけです。
package com.example.viewpagertest1.pageradapter;
import com.example.viewpagertest1.fragment.Fragment0;
import com.example.viewpagertest1.fragment.Fragment1;
import com.example.viewpagertest1.fragment.Fragment2;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class MyFragmentStatePagerAdapter
extends FragmentStatePagerAdapter {
public MyFragmentStatePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
switch(i){
case 0:
return new Fragment0();
case 1:
return new Fragment1();
default:
return new Fragment2();
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
ここでやっていることは次の三つだけです。
- getItem メソッドでそのインデックスに応じたフラグメントを返す。
- getCount メソッドでページ数を返す。
- getPageTitle メソッドでそのインデックスに応じたページのタイトルを返す。
フラグメントステートページャーアダプターを作ったら、あとは ViewPager にこのアダプターをセットすれば完了です。
package com.example.viewpagertest1;
import com.example.viewpagertest1.pageradapter
.MyFragmentStatePagerAdapter;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity {
ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(
new MyFragmentStatePagerAdapter(
getSupportFragmentManager()));
}
}
アダプターの設定には、上のコードの通り、setAdapter メソッドに渡せば OK です。