我们在使用Viewpager 的时候, 经常 会加入一些好看的滑动效果这个是怎么实现的呢?


其实很简单,  google 以及为我提供了相应的方法.


通过 setPageTransformer 就可以设置 Viewpager的滑动效果.



Android 官方文档 已经提供了两种 滑动效果:


http://developer.android.com/intl/zh-cn/training/animation/screen-slide.html



ZoomOutPageTransformer: 


android viewpager 居中旋转_滑动效果

public class ZoomOutPageTransformer 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(0);


         } 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(0);
         }
     }
 }

其实从google 给的两个demo 的注释中可以看出一些端倪.


在 transformPage 方法中, 会传递两个参数,


且 该View  对应 当前的 position



从注释中可以看到,  


position 有一下几个区间:


[-∞ , -1)  :


     表示左边 的View 且已经看不到了


[-1 ,   0]  :


     表示左边的 View ,且可以看见


( 0 ,   1]  :


     表示右边的VIew , 且可以看见了


( 1 , -∞)  :     


     表示右边的 View 且已经看不见了



上面讲的有些模糊,  举个例子



a 是第一页


b 是第二页


当前页为 a, 当  a  向左滑动,  直到滑到 b 时:


a 的position变化是  [-1 ,   0]   由  0  慢慢变到 -1


b 的position变化是  ( 0 ,   1]   由  1  慢慢变到  0



当前页为b,  当 b 向右滑动, 直到滑到a 时:


a 的position变化是  [-1 ,   0]   由  -1  慢慢变到 0


b 的position变化是  ( 0 ,   1]   由   0   慢慢变到 1



了解了这些后, 那么其他的事情 就是在更具position 来写不同的动画了




ok  之前有一篇博客 是写到 关于 Viewpager 来实现 画廊效果, 但是 没有滑动效果.


这里自定义一个  PageTransformer 来实现滑动效果:


先看图 


android viewpager 居中旋转_ide_02


可以看到 较 之前那篇博客 好看了很多, 下面上代码:

private static float defaultScale = (float) 14 / (float) 15; 



 public class MyPageTransformer implements ViewPager.PageTransformer { 

     @Override 

     public void transformPage(View view, float position) { 

         View cardView = view.findViewById(R.id.img_box); 

         View img = view.findViewById(R.id.img); 



         int diffWidth = (cardView.getWidth() - img.getWidth()) / 2; 



         if (position < -1) { // [-Infinity,-1) 

             cardView.setScaleX(defaultScale); 

             cardView.setScaleY(defaultScale); 

             img.setTranslationX(diffWidth); 



         } else if (position <= 0) { // [-1,0] 

             cardView.setScaleX((float) 1 + position / (float) 15); 

             cardView.setScaleY((float) 1 + position / (float) 15); 

             img.setTranslationX((0 - position) * diffWidth); 



         } else if (position <= 1) { // (0,1] 

             cardView.setScaleX((float) 1 - position / (float) 15); 

             cardView.setScaleY((float) 1 - position / (float) 15); 

             img.setTranslationX((0 - position) * diffWidth); 



         } else { // (1,+Infinity] 

             cardView.setScaleX(defaultScale); 

             cardView.setScaleY(defaultScale); 

             img.setTranslationX(-diffWidth); 

         } 

     } 

 }



其实很简单, 就是更具 position 处理向右的属性动画


当处于 [-Infinity,-1) 时,  是左边的看不见的, 则设在 scaleXY 缩小


当处于 [-Infinity,-1) 时,  是右边的看不见的, 则设在 scaleXY 缩小


当处于 [-Infinity,-1) 时,  是右边的看不见的, 则设在 scaleXY (float) 1 + position / (float) 15 更具 position来变化



需要注意的是,  除了设在 scaleXY  我还设置了 translationX


这是因为, 没 Item里面的土坯那 是wrap_content 且剧中


所以如果是长条状的图,  那么即使设在 android:clipChildren = false  页还是看不到 那张图,


这里 设在 setTranslationX 就是 吧 处于中间的长条状的图, 移到边上来, 


\