android ViewPager+fragment切换动画实现

Posted 踏雪羽翼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android ViewPager+fragment切换动画实现相关的知识,希望对你有一定的参考价值。

1、viewPager的fragment切换动画主要实现ViewPager.PageTransformer接口,然后修改下面几个参数实现各种不同的动画切换效果的。

  • setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) 透明度
  • setTranslationX(float translationX) X轴平移
  • setTranslationY(float translationY) Y轴平移
  • setTranslationZ(float translationZ) Z轴平移
  • setRotation(float rotation) 设置相对中心点的旋转角度,正值按照顺时针转动
  • setRotationX(float rotationX) 设置相对X轴(水平轴)旋转,正值为从X轴向下看顺时针旋转
  • setRotationY(float rotationY)设置相对Y轴(竖直轴)旋转,正值为从Y轴向下看顺时针旋转
  • setPivotX(float pivotX) 设置X轴附近的轴心点的X坐标
  • setPivotY(float pivotY) 设置Y轴附近的轴心点的Y坐标
  • setScaleX(float scaleX) 设置X轴方向的缩放比例
  • setScaleY(float scaleY) 设置Y轴方向的缩放比例
  • 参数page:这个是你即将把动画赋予的子页面
  • 一看是个float值,就要和作为int值的它区分开,float是个相对位置,它是一个-1到1的值,相对位置提供给开发者,可以控制动画进度和方式。 具体的:0的时候是要执行动画的页面处于页面前端并居中的位置, 1是要执行动画的页面向右移动到看不见(宽度为一整个页面), -1是要执行的动画向左移动到看不见的位置(宽度为一整个页面), 正好对应一个进入动画,一个退出动画。

2、先实现一个简单的效果,第一个页面以个角度退出,第二个页面以一个角度进入。实现代码只需几句

class MyPageTransformer implements ViewPager.PageTransformer 
        @Override
        public void transformPage(@NonNull View page, float position) 
            if (position <= 0f) 
             else if (position <= 1f) 
                page.setAlpha(1 - position);
            
            page.setRotationY(15f * position);
        

    

当滑动的时候第二页面以透明状态y轴旋转15度滑进来,然后就可以实现简单的切换动画效果,如果要视觉冲击感强一点可以修改y轴的旋转角度实现。

2、如果要实现类似3d的切换效果可以给x轴加个锚点控制,如下面代码

 class MyPageTransformer implements ViewPager.PageTransformer 
        @Override
        public void transformPage(@NonNull View page, float position) 
            //3D旋转
            int width = page.getWidth();
            int pivotX = 0;
            if (position <= 1 && position > 0) 
                pivotX = 0;
             else if (position == 0) 

             else if (position < 0 && position >= -1) 
                pivotX = width;
            
            //设置x轴的锚点
            page.setPivotX(pivotX);
            //设置绕Y轴旋转的角度
            page.setRotationY(90f * position);
        
    

3、想要实现上下页切换效果的可以通过修改它的缩放和透明度,就可以简单实现

class MyPageTransformer implements ViewPager.PageTransformer 
        private final float MIN_SCALE = 0.5f;
        private final float MIN_ALPHA = 0.5f;

        @Override
        public void transformPage(@NonNull View page, float position) 
            float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
            float alphaFactor = MIN_ALPHA + (1 - MIN_ALPHA) * (1 - Math.abs(position));
            page.setScaleY(scaleFactor);
            page.setAlpha(alphaFactor);
        

    

引用的话只需初始化的时候加一句代码便可

 mViewPager.setPageTransformer(true, new MyPageTransformer());

下面是一些网上写好的切换效果,可以参考

package com.coocent.musiclib.animation;

        import android.graphics.Camera;
        import android.graphics.Matrix;
        import android.support.annotation.NonNull;
        import android.support.v4.view.ViewPager;
        import android.view.View;

        import com.nineoldandroids.view.ViewHelper;

        import static java.lang.Math.min;

/**

 */
public class PageTransformerEffect implements ViewPager.PageTransformer 

    private int THREE_d = 0;
    private int ROTATE_EFFECT = 1;
    private int ALPHA_EFFECT = 2;
    private int DEGREE_EFFECT = 3;
    private int PAGE_TURNING_EFFECT = 4;
    private int ZOOM_IN_EFFECT = 5;
    private int ZOOM_OUT_EFFECT = 6;
    private int ZOOM_SLIDE_EFFECT = 7;
    private int ACCORDION_EFFECT = 8;
    private int BACKGROUND_TO_FORE = 9;
    private int CUBE_IN_EFFECT = 10;
    private int FLIP_HORIZONTAL_EFFECT = 11;
    private int FLIP_VERTICAL_EFFECT = 12;
    private int ROTATE_UP = 13;
    private int SCALE_IN_OUT = 14;
    private int STACK_EFFECT = 15;
    private int TABLE_EFFECT = 16;
    private int mEffect = 0;
    private float MIN_SCALE = 0.75f;
    private final float MIN_SCALE_ALPHA = 0.5f;
    private final float MIN_ALPHA = 0.5f;

    public PageTransformerEffect(int effect) 
        this.mEffect = effect;
    

    @Override
    public void transformPage(@NonNull View page, float position) 
        if (mEffect == THREE_d) 
            three_d(page, position);
         else if (mEffect == ROTATE_EFFECT) 
            setRotate(page, position);
         else if (mEffect == ALPHA_EFFECT) 
            setAlpha(page, position);
         else if (mEffect == DEGREE_EFFECT) 
            setDegree(page, position);
         else if (mEffect == PAGE_TURNING_EFFECT) 
            pageTurning(page, position);
         else if (mEffect == ZOOM_IN_EFFECT) 
            zoomIn(page, position);
         else if (mEffect == ZOOM_OUT_EFFECT) 
            zoomOut(page, position);
         else if (mEffect == ZOOM_SLIDE_EFFECT) 
            zoomSlide(page, position);
         else if (mEffect == ACCORDION_EFFECT) 
            accordion(page, position);
         else if (mEffect == BACKGROUND_TO_FORE) 
            backgroundToForeground(page, position);
         else if (mEffect == CUBE_IN_EFFECT) 
            cubeIn(page, position);
         else if (mEffect == FLIP_HORIZONTAL_EFFECT) 
            flipHorizontal(page, position);
         else if (mEffect == FLIP_VERTICAL_EFFECT) 
            flipVertical(page, position);
         else if (mEffect == ROTATE_UP) 
            rotateUp(page, position);
         else if (mEffect == SCALE_IN_OUT) 
            scaleInOut(page, position);
         else if (mEffect == STACK_EFFECT) 
            stack(page, position);
         else if (mEffect == TABLE_EFFECT) 
            table(page, position);
        
    

    private void three_d(View page, float position) 
//3d旋转
        int width = page.getWidth();
        int pivotX = 0;
        if (position <= 1 && position > 0) // right scrolling
            pivotX = 0;
         else if (position == 0) 

         else if (position < 0 && position >= -1) // left scrolling
            pivotX = width;
        
//设置x轴的锚点
        page.setPivotX(pivotX);
//设置绕Y轴旋转的角度
        page.setRotationY(90f * position);
    

    private void setRotate(View page, float position) 

        if (position <= 0f) 
            page.setTranslationX(0f);
            page.setScaleX(1f);
            page.setScaleY(1f);
         else if (position <= 1f) 
            final float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
            page.setAlpha(1 - position);
            page.setPivotY(0.5f * page.getHeight());
            page.setTranslationX(page.getWidth() * -position);
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);
        
        page.setRotation(180 * position);
    

    private void setAlpha(View page, float position) 
        float scaleFactor = MIN_SCALE_ALPHA + (1 - MIN_SCALE_ALPHA) * (1 - Math.abs(position));
        float alphaFactor = MIN_ALPHA + (1 - MIN_ALPHA) * (1 - Math.abs(position));
        page.setScaleY(scaleFactor);
        page.setAlpha(alphaFactor);
    

    private void setDegree(View page, float position) 
        int pageWidth = page.getWidth();
        if (position < -1)  // [-Infinity,-1)
// This page is way off-screen to the left.
// view.setAlpha(0);
            ViewHelper.setAlpha(page, 0);
         else if (position <= 0)// a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0
         // [-1,0]
// Use the default slide transition when moving to the left page
// view.setAlpha(1);
            ViewHelper.setAlpha(page, 1);
// view.setTranslationX(0);
            ViewHelper.setTranslationX(page, 0);
// view.setScaleX(1);
            ViewHelper.setScaleX(page, 1);
// view.setScaleY(1);
            ViewHelper.setScaleY(page, 1);
         else if (position <= 1)  // (0,1]
// Fade the page out.
// view.setAlpha(1 - position);
            ViewHelper.setAlpha(page, 1 - position);
// Counteract the default slide transition
// view.setTranslationX(pageWidth * -position);
            ViewHelper.setTranslationX(page, pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - position);
// view.setScaleX(scaleFactor);
            ViewHelper.setScaleX(page, scaleFactor);
// view.setScaleY(1);
            ViewHelper.setScaleY(page, scaleFactor);
         else  // (1,+Infinity]
// This page is way off-screen to the right.
// view.setAlpha(0);
            ViewHelper.setAlpha(page, 1);
        
    

    private static final float ROT_MAX = 20.0f;
    private float mRot;

    private void pageTurning(View page, float position) 
        if (position < -1)  // [-Infinity,-1)
// This page is way off-screen to the left.
            ViewHelper.setRotation(page, 0);
         else if (position <= 1) // a页滑动至b页 ; a页从 0.0 ~ -1 ;b页从1 ~ 0.0
         // [-1,1]
// Modify the default slide transition to shrink the page as well
            if (position < 0) 
                mRot = (ROT_MAX * position);
                ViewHelper.setPivotX(page, page.getMeasuredWidth() * 0.5f);
                ViewHelper.setPivotY(page, page.getMeasuredHeight());
                ViewHelper.setRotation(page, mRot);
             else 
                mRot = (ROT_MAX * position);
                ViewHelper.setPivotX(page, page.getMeasuredWidth() * 0.5f);
                ViewHelper.setPivotY(page, page.getMeasuredHeight());
                ViewHelper.setRotation(page, mRot);
            
// Scale the page down (between MIN_SCALE and 1)
// Fade the page relative to its size.
         else  // (1,+Infinity]
// This page is way off-screen to the right.
            ViewHelper.setRotation(page, 0);
        
    

    private void zoomIn(View page, float position) 
        final float scale = position < 0 ? position + 1f : Math.abs(1f - position);
        page.setScaleX(scale);
        page.setScaleY(scale);
        page.setPivotX(page.getWidth() * 0.5f);
        page.setPivotY(page.getHeight() * 0.5f);
        page.setAlpha(position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
    

    private void zoomOut(View page, float position) 
        int pageWidth = page.getWidth();
        int pageHeight = page.getHeight();

        if (position < -1)  // [-Infinity,-1)
// This page is way off-screen to the left.
            page.setAlpha(0);
         else if (position <= 1)  // [-1,1]
// Modify the default slide transition to
// shrink the page as well
            float scaleFactor = Math.max(0.85f, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
            if (position < 0) 
                page.setTranslationX(horzMargin - vertMargin / 2);
             else 
                page.setTranslationX(-horzMargin + vertMargin / 2);
            
// Scale the page down (between MIN_SCALE and 1)
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);
// Fade the page relative to its size.
            page.setAlpha(MIN_ALPHA + (scaleFactor - 0.85f)
                    / (1 - 0.85f) * (1 - MIN_ALPHA));
         else  // (1,+Infinity]
// This page is way off-screen to the right.
            page.setAlpha(0);
        
    


    private void zoomSlide(View page, float position) 
        if (position >= -1 || position <= 1) 
// Modify the default slide transition to shrink the page as well
            final float height = page.getHeight();
            final float width = page.getWidth();
            final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            final float vertMargin = height * (1 - scaleFactor) / 2;
            final float horzMargin = width * (1 - scaleFactor) / 2;

// Center vertically
            page.setPivotY(0.5f * height);
            page.setPivotX(0.5f * width);

            if (position < 0) 
                page.setTranslationX(horzMargin - vertMargin / 2);
             else 
                page.setTranslationX(-horzMargin + vertMargin / 2);
            

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

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

    private void accordion(View page, float position) 
        page.setPivotX(position < 0 ? 0 : page.getWidth());
        page.setScaleX(position < 0 ? 1f + position : 1f - position);
    

    private void backgroundToForeground(View page, float position) 
        final float height = page.getHeight();
        final float width = page.getWidth();
        final float scale = min(position < 0 ? 1f : Math.abs(1f - position), 0.5f);

        page.setScaleX(scale);
        page.setScaleY(scale);
        page.setPivotX(width * 0.5f);
        page.setPivotY(height * 0.5f);
        page.setTranslationX(position < 0 ? width * position : -width * position * 0.25f);
    

    private void cubeIn(View page, float position) 
        page.setPivotX(position > 0 ? 0 : page.getWidth());
        page.setPivotY(0);
        page.setRotationY(-90f * position);
    

    private void flipHorizontal(View page, float position) 
        final float rotation = 180f * position;
        page.setAlpha(rotation > 90f || rotation < -90f ? 0 : 1);
        page.setPivotX(page.getWidth() * 0.5f);
        page.setPivotY(page.getHeight() * 0.5f);
        page.setRotationY(rotation);
    

    private void flipVertical(View page, float position) 
        final 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);
    

    private void rotateUp(View page, float position) 
        float ROT_MOD = -15f;
        final float width = page.getWidth();
        final float rotation = ROT_MOD * position;

        page.setPivotX(width * 0.5f);
        page.setPivotY(0f);
        page.setTranslationX(0f);
        page.setRotation(rotation);
    

    private void scaleInOut(View page, float position) 
        page.setPivotX(position < 0 ? 0 : page.getWidth());
        page.setPivotY(page.getHeight() / 2f);
        float scale = position < 0 ? 1f + position : 1f - position;
        page.setScaleX(scale);
        page.setScaleY(scale);
    

    private void stack(View page, float position) 
        page.setTranslationX(position < 0 ? 0f : -page.getWidth() * position);
    

    private void table(View page, float position) 
        final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);

        page.setTranslationX(getOffsetXForRotation(rotation, page.getWidth(), page.getHeight()));
        page.setPivotX(page.getWidth() * 0.5f);
        page.setPivotY(0);
        page.setRotationY(rotation);
    

    private static final Matrix OFFSET_MATRIX = new Matrix();
    private static final Camera OFFSET_CAMERA = new Camera();
    private static final float[] OFFSET_TEMP_FLOAT = new float[2];

    protected static final 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);
    

如果想要做出各种不同的酷炫效果可以根据上面的参数修改搭配做出自己想要的效果。

 

以上是关于android ViewPager+fragment切换动画实现的主要内容,如果未能解决你的问题,请参考以下文章

Fragment嵌套ViewPager切换后数据消失ViewPager空白问题

删除 viewPager2 中的片段使用 FragmentStateAdapter,但仍显示

如何在同一页面上的 Fragment 内创建具有 3 个 Fragment 的 ViewPager?

gitee查询用户名和密码 Android Studio 3.5以上版本新特性 sharePreferences 使用 不同的Activity间的preferences共享问题 Fragmen

如何防止创建相同片段的 2 个实例?

android怎么viewpager实现循环切换图片