前提准备:写一个简单的ViewPager的demo

布局文件:setting_activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_marginBottom="10dp"
    >
    <!--android:clipChildren="false" 允许子view溢出当前父View-->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        >

    </androidx.viewpager.widget.ViewPager>


</RelativeLayout>
public class SettingsActivity extends AppCompatActivity {
    private int[] mDrawables = {R.drawable.a1, R.drawable.a2, R.drawable.a3};
    //用来记录是否按压,如果按压,则不滚动
    boolean isDown;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        ViewPager viewPager = findViewById(R.id.vp);

        viewPager.setAdapter(new TBannerAdapter(this, mDrawables));

        viewPager.setPageMargin(20);//item之间的间距
        //预加载
        viewPager.setOffscreenPageLimit(3);
        //默认第一张图 左右都有图
        viewPager.setCurrentItem(1);


    }


}
package com.android.myapplication;

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;


/**
 * 画廊效果:
 * 让ViewPager显示出左右两侧的View   android:clipChildren="false"
 * 无限滑动   设置个max值---Integer.MAX_VALUE
 * 自定义ViewPager滑动动画,滑动过程中中间大,两边小  复写Viewpager的PageTransformer
 * 自动播放
 */
public class TBannerAdapter extends PagerAdapter {
    private  int [] mData;
    private Context mContext;

    public TBannerAdapter(Context context,int [] data){
        mContext = context;
        mData = data;
    }
    @Override
    public int getCount() {
       return Integer.MAX_VALUE;
       // return mData.length;
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;//过滤和缓存
    }

    @NonNull
    @Override //初始化滑动的布局Item
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        View view = View.inflate(container.getContext(),R.layout.viewpager_item,null);
        ImageView imageView = view.findViewById(R.id.icon);
        imageView.setImageResource(mData[position % mData.length]);

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Log.d("tww","当前的Item:"+position);
            }
        });
        //添加到父布局
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }
}

在demo的基础上改动,实现自己想要的效果。

目的:在滑动的时候,让page页滑动时产生我们想要的动画效果,但是我们不知道动画效果添加在哪里?可以去查看Viewpager的源码或者百度?看page页滑动是调用了什么方法?

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //viewPager滑动的时候,设置不让滚动
        isDown = true;
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        //ViewPager不点击了让滚动
        isDown = false;
    }
});

ViewPager.java (源码)

@CallSuper
protected void onPageScrolled(int position, float offset, int offsetPixels) {
    // Offset any decor views if needed - keep them on-screen at all times.
    ........
    if (mPageTransformer != null) {
        final int scrollX = getScrollX();
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.isDecor) continue;
            final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
            mPageTransformer.transformPage(child, transformPos);
        }
    }
    mCalledSuper = true;
}

 当page页滑动是,会调用transformPage()这个方法。

下面就是实例了,代码有注释 ,我也只是拙劣的模仿:

/**
 * 缩放,轮播图
 */

//这个方法transformPage在ViewPager.onPageScrolled页面滑动的过程中回调
public class SaclePageTransformer implements ViewPager.PageTransformer {
    private static final float MAX_SCALE = 1.0f;//不缩放
    private static final float MIN_SCALE = 0.80f;//缩放

    //对给定页面应用属性转换   换页
    @Override
    public void transformPage(@NonNull View page, float position) {
        // 没有滑动  0(左) 1(当前) 2(右) ====>   滑动一张  -1 0 1
        //position != 0 表示 左右两边的page
        /*if (position != 0) {
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
        } else {
            page.setScaleX(MAX_SCALE);
            page.setScaleY(MAX_SCALE);
        }*/
        // 向左滑动: [ position < 0 && position > -1]
        // 向右滑动: [position > 0 && position < 1 ]
        /*
        * for (int i = 0; i < childCount; i++) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (lp.isDecor) continue;
                final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
                mPageTransformer.transformPage(child, transformPos);
            }
        * */
        Log.d("tww", position + "");
        if (position < 1) {
            //重点:指的就是变化过程中view的大小   动画更丝滑
            float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE);//算法
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);
        } else {
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
        }
    }
}
/**
 * 相册,stack动画效果
 */
public class StackPageTransformer implements ViewPager.PageTransformer {
    private final ViewPager viewPager;

    private final float SCALE_VALUE = 1f;

    //View 之间的偏移量
    private final float DEVIATION = 60f;

    //旋转
    private final float ROTATION = 60f;

    //图片是否叠加【默认不叠加】
    private final boolean isStack = false;


    public StackPageTransformer(ViewPager viewPager) {
        this.viewPager = viewPager;
    }

    @Override
    public void transformPage(@NonNull View view, float position) {
        Log.d("tww", position + "");

        /*
         * 当不滑动状态下:
         *      position = -1 左侧View
         *      position = 0 当前View
         *      position = 1 右侧View
         *
         * 当滑动状态下:
         *  向左滑动: [ position < 0 && position > -1]
         *    左侧View      position < -1
         *    当前View    0 ~ -1
         *    右侧View   1 ~ 0
         *
         * 向右滑动:[position > 0 && position < 1 ]
         *   左侧View  -1 < position < 0
         *   当前View  0 ~ 1
         *   右侧View  position > 1
         */

        int pageWidth = viewPager.getWidth();

        //隐藏左侧侧的view
        if (position == -1) {
            view.setVisibility(View.GONE);
        } else {
            view.setVisibility(View.VISIBLE);
        }

        //当前View和右侧的View [让右侧View和当前View叠加起来]
        if (position >= 0) {
            float translationX;
            //这里不要晕! 改变isStack来看看效果吧!!
            if (isStack) {
                translationX = DEVIATION - (pageWidth) * position;
            } else {
                translationX = (DEVIATION - pageWidth) * position;
            }
            Log.d("tww", translationX + "");
            view.setTranslationX(translationX);
        }

        //当前view
        if (position == 0) {
            view.setScaleX(SCALE_VALUE);
            view.setScaleY(SCALE_VALUE);
        } else {
            //左侧已经隐藏了,所以这里值的是右侧View的偏移量
            float scaleFactor = Math.min(SCALE_VALUE - position * 0.1f, SCALE_VALUE);
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);
        }

        //向左滑动
        if (position < 0 && position > -1) {
            //旋转
            view.setRotation(ROTATION * position);
            view.setAlpha(1 - Math.abs(position));
        } else {
            //透明度 其他状态不设置透明度
            view.setAlpha(1);
        }

        //向右滑动
        if (position > 0 && position < 1) {
            view.setRotation(0);
        }
    }
}
public class SettingsActivity extends AppCompatActivity {
    private int[] mDrawables = {R.drawable.a1, R.drawable.a2, R.drawable.a3};
    //用来记录是否按压,如果按压,则不滚动
    boolean isDown ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        ViewPager viewPager = findViewById(R.id.vp);

        viewPager.setAdapter(new TBannerAdapter(this, mDrawables));

        viewPager.setPageMargin(20);//item之间的间距
        //预加载
        viewPager.setOffscreenPageLimit(3);
        //默认第一张图 左右都有图
        viewPager.setCurrentItem(1);

        //缩放,轮播图
        viewPager.setPageTransformer(true,new SaclePageTransformer());
        //旋转,相册
        //viewPager.setPageTransformer(true,new StackPageTransformer(viewPager));



        //利用Timer计时器实现自动轮播
        Timer timer = new Timer();
        //定时器播放ViewPager
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                if (!isDown) {
                    //获取到当前的位置
                    int page = viewPager.getCurrentItem() + 1;
                    runOnUiThread(() -> viewPager.setCurrentItem(page));
                }
            }
        };
        // 每2.5秒执行一次 
        timer.schedule(timerTask, 0, 2500);

        //Viewpager监听
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //viewPager滑动的时候,设置不让滚动
                isDown = true;
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                //ViewPager不点击了让滚动
                isDown = false;
            }
        });

    }

}