Android学习android 自定义View

ViewPager<第二篇>:实现翻页动画

2019-11-29  本文已影响0人  NoBugException

为ViewPager提供动画效果,显然,使得UI变得用户更加友好,所以它的作用可想而知。

ViewPager为我们提供了setPageTransformer方法可以设置切换动画

public void setPageTransformer(boolean reverseDrawingOrder, @Nullable PageTransformer transformer)

reverseDrawingOrder:若为true,属性动画倒序播放;若为false,则正序播放;
transformer:为每个页面设置切换动画;

为了实现ViewPager的切换动画,必须自定义DepthPageTransformer,基本代码如下:

public class MyPageTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

    }
}

创建一个MyPageTransformer类,实现ViewPager.PageTransformer,重写方法transformPagetransformPage方法有两个参数,分别是pageposition

ViewPager的切换动画总是在transformPage方法中实现的,那么现在就贴出整理之后的案例吧。

【案例一】 折叠翻页特效

效果演示:

320.gif

代码如下:

public class AccordionTransformer implements ViewPager.PageTransformer  {

    @Override
    public void transformPage(@NonNull View page, float position) {

        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setScaleX(1f);
            page.setTranslationX(0);
        } else if (position <= 0) { // [-1,0]
            page.setPivotX(0f);
            page.setTranslationX(-position * page.getWidth());
            page.setScaleX(position + 1);
        } else if (position <= 1) { // (0,1]
            page.setPivotX(page.getWidth());
            page.setTranslationX(-position * page.getWidth());
            page.setScaleX(1-position);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setScaleX(1f);
            page.setTranslationX(0);
        }

    }

}

【案例二】 前台到后台,后台到前台的切换动画

效果演示:

321.gif

代码如下:

public class BackgroundAndForegroundTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {


        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        if (position < -1) { // [-Infinity,-1)
            page.setScaleX(1f);
            page.setScaleY(1f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setTranslationX(0);
        } else if (position <= 0) { // [-1,0]
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setScaleX(1 + position);
            page.setScaleY(1 + position);
            page.setTranslationX(-page.getWidth() * position * 0.5f);
        } else if (position <= 1) { // (0,1]
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setScaleX(1 - position);
            page.setScaleY(1 - position);
            page.setTranslationX(page.getWidth() * position * 0.5f);

        } else { // (1,+Infinity]
            page.setScaleX(1f);
            page.setScaleY(1f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setTranslationX(0);
        }

    }
}

【案例三】 立方体内部切换动画

效果演示:

322.gif

代码如下:

public class CubeInTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        page.setCameraDistance(page.getWidth() * 20);

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX();
            page.setPivotY(0f);
            page.setRotationY(0);
        } else if (position <= 0) { // [-1,0]
            page.setPivotX(page.getWidth());
            page.setPivotY(0f);
            page.setRotationY(-90f * position);
        } else if (position <= 1) { // (0,1]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(-90f * position);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        }
    }
}

【案例四】 立方体外部切换动画

效果演示:

323.gif

代码如下:

public class CubeInTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        page.setCameraDistance(page.getWidth() * 20);

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        } else if (position <= 0) { // [-1,0]
            page.setPivotX(page.getWidth());
            page.setPivotY(0f);
            page.setRotationY(-90f * position);
        } else if (position <= 1) { // (0,1]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(-90f * position);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        }
    }
}

【案例五】 深度页面切换

效果演示:

324.gif

代码如下:

public class DepthPageTransformer implements ViewPager.PageTransformer {


    private static float MIN_SCALE = 0.75f;

    @Override
    public void transformPage(@NonNull View page, float position) {

        int pageWidth = page.getWidth();
        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            page.setAlpha(0);
        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            page.setAlpha(1);
            page.setTranslationX(0);
            page.setScaleX(1);
            page.setScaleY(1);
        } else if (position <= 1) { // (0,1]
            // Fade the page out.
            page.setAlpha(1 - position);
            // Counteract the default slide transition
            page.setTranslationX(pageWidth * -position);
            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);
        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            page.setAlpha(0);
        }

    }
}

【案例六】 抽屉式页面切换

效果演示:

325.gif

代码如下:

public class DrawerTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        page.setCameraDistance(page.getWidth() * 20);

        if (position < -1) { // [-Infinity,-1)
            page.setTranslationX(0);
        } else if (position <= 0) { // [-1,0]
            page.setTranslationX(0);
        } else if (position <= 1) { // (0,1]
            page.setTranslationX(-page.getWidth() / 2 * position);
        } else { // (1,+Infinity]
            page.setTranslationX(0);
        }

    }
}

【案例七】 横向开关页面切换

效果演示:

326.gif

代码如下:

public class FlipHorizontalTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        //只对[-1,1]之间处理,超过范围将属性设置为初始值

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        } else if (position <= 1) { // (0,1]
            float rotation = 180f * position;
            page.setAlpha(rotation > 90f || rotation < -90f ? 0f : 1f);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setRotationY(rotation);
            page.setTranslationX(-page.getWidth() * position);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        }

        page.setVisibility(position > -0.5f && position < 0.5f ? View.VISIBLE : View.INVISIBLE);
    }
}

【案例八】 纵向开关页面切换

效果演示:

327.gif

代码如下:

public class FlipVerticalTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setAlpha(0f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationX(0f);
            page.setTranslationX(0f);
        } else if (position <= 1) { // [-1,0]
            float rotation = -180f * position;
            page.setAlpha(rotation > 90f || rotation < -90f ? 0f : 1f);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setRotationX(rotation);
            page.setTranslationX(-page.getWidth() * position);
        }else { // (1,+Infinity]
            page.setAlpha(0f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationX(0f);
            page.setTranslationX(0f);
        }
        page.setVisibility(position > -0.5f && position < 0.5f ? View.VISIBLE : View.INVISIBLE);
    }

}

【案例九】 向下旋转页面切换

效果演示:

328.gif

代码如下:

public class RotateDownTransformer implements ViewPager.PageTransformer {

    private static float ROT_MOD = 18.75f;

    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        } else if (position <= 1) { // [-1,0]
            float width = page.getWidth();
            float height = page.getHeight();
            float rotation = ROT_MOD * position;
            page.setPivotX(width * 0.5f);
            page.setPivotY(height);
            page.setRotation(rotation);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        }
    }
}

【案例十】 向上旋转页面切换

效果演示:

329.gif

代码如下:

public class RotateUpTransformer implements ViewPager.PageTransformer {

    private static float ROT_MOD = -15f;

    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        } else if (position <= 1) { // [-1,0]
            float width = page.getWidth();
            float rotation = ROT_MOD * position;
            page.setPivotX(width * 0.5f);
            page.setPivotY(0f);
            page.setRotation(rotation);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
        }
    }
}

【案例十一】 缩放效果的页面切换

效果演示:

330.gif

代码如下:

public class ScaleInOutTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setTranslationX(0f);
            page.setScaleX(0f);
            page.setScaleY(0f);
        } else if (position <= 0) { // [-1,0]
            page.setPivotX(0);
            page.setPivotY(page.getHeight() / 2f);
            page.setTranslationX(-page.getWidth() * position);
            page.setScaleX(1f + position);
            page.setScaleY(1f + position);
        } else if (position <= 1) { // (0,1]
            page.setPivotX(page.getWidth());
            page.setPivotY(page.getHeight() / 2f);
            page.setTranslationX(-page.getWidth() * position);
            page.setScaleX(1f - position);
            page.setScaleY(1f - position);
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setTranslationX(0f);
            page.setScaleX(0f);
            page.setScaleY(0f);
        }
    }

}

【案例十二】 堆叠页面切换

效果演示:

331.gif

代码如下:

public class StackTransformer implements ViewPager.PageTransformer {


    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setTranslationX(0f);
        } else if (position <= 0) { // [-1,0]
            page.setTranslationX(0f);
        } else if (position <= 1) { // (0,1]
            page.setTranslationX(-page.getWidth() * position);
        } else { // (1,+Infinity]
            page.setTranslationX(0f);
        }
        
    }

}

【案例十三】 纪念牌页面切换

效果演示:

332.gif

代码如下:

public class TabletTransformer implements ViewPager.PageTransformer {

    private Matrix OFFSET_MATRIX = new Matrix();
    private Camera OFFSET_CAMERA = new Camera();
    private float[] OFFSET_TEMP_FLOAT = new float[2];
    private float ROT_MOD = 30f;

    protected float getOffsetXForRotation(float degrees, int width, int height) {
        OFFSET_MATRIX.reset();
        OFFSET_CAMERA.save();
        OFFSET_CAMERA.rotateY(Math.abs(degrees));
        OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
        OFFSET_CAMERA.restore();

        OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
        OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
        OFFSET_TEMP_FLOAT[0] = width;
        OFFSET_TEMP_FLOAT[1] = height;
        OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
        return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
    }


    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
            page.setTranslationX(0);
        } else if (position <= 1) { // [-1,0]
            float rotation = position < 0 ? ROT_MOD : -ROT_MOD;
            float rotationY = rotation * Math.abs(position);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(0f);
            page.setRotationY(rotationY);
            page.setTranslationX(getOffsetXForRotation(rotationY, page.getWidth(), page.getHeight()));
        } else { // (1,+Infinity]
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setRotationY(0);
            page.setTranslationX(0);
        }
    }
}

【案例十四】 内部缩放页面切换

效果演示:

333.gif

代码如下:

public class ZoomInTransformer implements ViewPager.PageTransformer {


    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setScaleX(0);
            page.setScaleY(0);
            page.setTranslationX(0);
            page.setPivotX(0);
            page.setPivotY(0);
            page.setAlpha(0);
        } else if (position <= 0) { // [-1,0]
            page.setScaleX(position + 1f);
            page.setScaleY(position + 1f);
            page.setTranslationX(-page.getWidth() * position);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setAlpha(1f - position);
        } else if (position <= 1) { // (0,1]
            page.setScaleX(1f - position);
            page.setScaleY(1f - position);
            page.setTranslationX(-page.getWidth() * position);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setAlpha(1f + position);
        } else { // (1,+Infinity]
            page.setScaleX(0);
            page.setScaleY(0);
            page.setTranslationX(0);
            page.setPivotX(0);
            page.setPivotY(0);
            page.setAlpha(0);
        }
    }
}

【案例十五】 外部缩放页面切换

效果演示:

334.gif

代码如下:

public class ZoomOutTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {

        if (position < -1) { // [-Infinity,-1)
            page.setScaleX(1f);
            page.setScaleY(1f);
            page.setTranslationX(0f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setAlpha(0f);
        } else if (position <= 0) { // [-1,0]
            float scale = 1f -position;
            page.setScaleX(scale);
            page.setScaleY(scale);
            page.setTranslationX(-page.getWidth() * position);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setAlpha(1f + position);
            if (position == -1f){
                page.setTranslationX(page.getWidth() * -1);
            }
        } else if (position <= 1) { // (0,1]
            float scale = 1f + position;
            page.setScaleX(scale);
            page.setScaleY(scale);
            page.setTranslationX(-page.getWidth() * position);
            page.setPivotX(page.getWidth() * 0.5f);
            page.setPivotY(page.getHeight() * 0.5f);
            page.setAlpha(1f - position);
        } else { // (1,+Infinity]
            page.setScaleX(1f);
            page.setScaleY(1f);
            page.setTranslationX(0f);
            page.setPivotX(0f);
            page.setPivotY(0f);
            page.setAlpha(0f);
        }
    }
}

【案例十六】 缩小页面的页面切换

当在相邻页面之间滚动时,此页面转换器将缩小和淡入页面。当一个页面靠近中心时,它会变回原来的大小并逐渐消失。

效果演示:

335.gif

代码如下:

public class ZoomOutSlideTransformer implements ViewPager.PageTransformer {

    private static final float MIN_SCALE = 0.85f;
    private static final float MIN_ALPHA = 0.5f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0f);

        } else if (position <= 1) { // [-1,1]
            // Modify the default slide transition to shrink the page as well
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
            if (position < 0) {
                view.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                view.setTranslationX(-horzMargin + vertMargin / 2);
            }

            // Scale the page down (between MIN_SCALE and 1)
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

            // Fade the page relative to its size.
            view.setAlpha(MIN_ALPHA +
                    (scaleFactor - MIN_SCALE) /
                            (1 - MIN_SCALE) * (1 - MIN_ALPHA));

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0f);
        }
    }
}

以上16中翻页效果的实现代码送给大家。

[本章完...]

上一篇下一篇

猜你喜欢

热点阅读