support-v4ライブラリのViewPager.PageTransformer
を使うと、ViewPagerをスワイプしたときのアニメーションをカスタマイズできます。
新しいものではありませんが、最近試したのでメモしておきます。
以下のトレーニングに詳しく書いてありますが、実際に実装してみた結果から、ポイントだけに絞りサンプルを交えて書いてみます。
Using ViewPager for Screen Slides
作り方
-
ViewPager.PageTransformer
を実装したクラスを作る -
transformPage
メソッドを実装する - 作ったクラスを
ViewPager#setPageTransformer()
で設定する
これだけです。
一つずつ、もう少し詳しく書きます。
例えば、スワイプするとフェードイン&アウトして切り替わるアニメーションを作る場合です。
ViewPager.PageTransformerを実装したクラスを作る
これは詳しく書くまでもないですが、ViewPager.PageTransformerをimplementsしたクラスを作ります。
public class FadePageTransformer implements ViewPager.PageTransformer {
transformPageメソッドを実装する
メソッドのシグニチャは以下です。
public void transformPage(View page, float position)
Viewがある位置(position)に表示されているときにどのような変化を加えるか?という感じでsetAlpha
やsetTranslationX
などで状態を変えていきます。
ここが工夫のしどころです。
positionは以下のように-1から1の間で相対的な位置を示しています。
| position | Viewの状態 |
|:--:+--------------------|
| -1 | 完全に左端に消えている |
| 0 | ちょうど中央に表示されている |
| 1 | 完全に右端に消えている |
このpositionによってViewを移動させたくない場合は、以下のようにpositionとViewの幅を使って逆向きに移動させます。
int pageWidth = page.getWidth();
page.setTranslationX(pageWidth * -position);
一例ですが、フェードの場合は以下のようになります。
@Override
public void transformPage(View page, float position) {
float alpha = 0;
int pageWidth = page.getWidth();
if (-1 < position && position < 0) {
// 左にスワイプしていくにつれ透明にする
alpha = position + 1;
} else if (0 <= position && position <= 1) {
// 右にスワイプしていくにつれ透明にする
alpha = 1 - position;
}
page.setAlpha(alpha);
// 逆方向に移動させることで位置を固定する
page.setTranslationX(pageWidth * -position);
}
作ったクラスをViewPager#setPageTransformer()で設定する
以下のようにViewPagerに新しいインスタンスを設定するだけです。
private ViewPager mPager;
:
mPager.setPageTransformer(false, new FadePageTransformer());
フェードなので分かりにくいですが、以下のようにスワイプ中は2枚のページが薄く重なって表示されます。
setPageTransformerの補足
第1引数が少し分かりにくいですが、後ろのページから順に描画させたい場合にtrueを指定します。
例えば以下のように1ページ目が2ページ目の上に重なって描画されるような遷移にしたい場合、第1引数にtrueを設定しておかないと2ページ目の方が上に描画されてしまいます。
逆に、以下のように先頭のページから順に描画される必要のある場合はfalseを指定します。