ViewPager 切换视差效果 Parallax Effect

实现类似雅虎天气(Yahoo Weather App)ViewPager 切换时的视差效果 parallax effect:ViewPager 背景图片的移动速度比内容的移动速度慢一倍。

使用方法:

  1. 需要为 ViewPager 的 Fragment 定义 background view;
  2. 把 background view id 传给 PagerTransformerParallax 构造器;
  3. 设置 ViewPager 的切换效果 viewPager.setPageTransformer()

原理:PagerTransformerParallax 通过构造器获取了 ViewPager fragment background view 的 id,因此就能引用到并改变 background view 的行为。通过继承接口 ViewPager.PageTransformer,并覆写方法 transformPage(),调用 setTranslationX() 来修改 background view 的位置。

Refer to: https://github.com/li2/Learning_Android_Open_Source/commit/21f15d49dfa297041ecd03f25be7685a22d2b4f4

public class PagerTransformerParallax implements ViewPager.PageTransformer {
    private int id;

    public PagerTransformerParallax(int id) {
        this.id = id;
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void transformPage(View view, float position) {
        View backgroundView = view.findViewById(id);
        if (backgroundView != null && Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB ) {
            if (position > -1 && position < 1) {
                float width = view.getWidth();
                backgroundView.setTranslationX(-width * position * 0.5f);
            }
        }
    }
}
// Activity
mPager.setPageTransformer(false, new PagerTransformerParallax(R.id.pagerBackground));

// Fragment hosted by ViewPager
// Set background drawable
int drawableId = R.drawable.*;
(rootView.findViewById(R.id.pagerBackground)).setBackgroundResource(drawableId);

fragment.xml

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Fragment background,
    this id should be used in PagerTransformerParallax constructor -->
    <View
        android:id="@+id/pagerBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/background1"/>

    <!-- Fragment content of ViewPager-->
</FrameLayout>