Android

AndroidのViewPager.PageTransformerでスライドアニメーションを作る

More than 3 years have passed since last update.

support-v4ライブラリのViewPager.PageTransformerを使うと、ViewPagerをスワイプしたときのアニメーションをカスタマイズできます。

新しいものではありませんが、最近試したのでメモしておきます。

以下のトレーニングに詳しく書いてありますが、実際に実装してみた結果から、ポイントだけに絞りサンプルを交えて書いてみます。

Using ViewPager for Screen Slides


作り方



  1. ViewPager.PageTransformerを実装したクラスを作る


  2. transformPageメソッドを実装する

  3. 作ったクラスをViewPager#setPageTransformer()で設定する

これだけです。

一つずつ、もう少し詳しく書きます。

例えば、スワイプするとフェードイン&アウトして切り替わるアニメーションを作る場合です。


ViewPager.PageTransformerを実装したクラスを作る

これは詳しく書くまでもないですが、ViewPager.PageTransformerをimplementsしたクラスを作ります。


FadePageTransformer.java

public class FadePageTransformer implements ViewPager.PageTransformer {



transformPageメソッドを実装する

メソッドのシグニチャは以下です。

public void transformPage(View page, float position)

Viewがある位置(position)に表示されているときにどのような変化を加えるか?という感じでsetAlphasetTranslationXなどで状態を変えていきます。

ここが工夫のしどころです。

positionは以下のように-1から1の間で相対的な位置を示しています。

position
Viewの状態

-1
完全に左端に消えている

0
ちょうど中央に表示されている

1
完全に右端に消えている

このpositionによってViewを移動させたくない場合は、以下のようにpositionとViewの幅を使って逆向きに移動させます。

int pageWidth = page.getWidth();

page.setTranslationX(pageWidth * -position);

一例ですが、フェードの場合は以下のようになります。


FadePageTransformer.java

@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枚のページが薄く重なって表示されます。

device-2014-07-01-003308.png


setPageTransformerの補足

第1引数が少し分かりにくいですが、後ろのページから順に描画させたい場合にtrueを指定します。

例えば以下のように1ページ目が2ページ目の上に重なって描画されるような遷移にしたい場合、第1引数にtrueを設定しておかないと2ページ目の方が上に描画されてしまいます。

device-2014-07-01-001437.png

逆に、以下のように先頭のページから順に描画される必要のある場合はfalseを指定します。

device-2014-07-01-001610.png