ViewPager实现一个层叠的卡片,先看看效果
层叠卡片我将其用在了APP的引导页面上,这个效果虽然看上去很难,但实际上实现起来特别的简单,主要是使用PageTransformer来实现这个效果,推荐先看一下hongyang的前置教程:Android 自定义 ViewPager 打造千变万化的图片切换效果,请确保你已经掌握前置,原理里都写了,就不在累述.(主要还是因为太懒了)
正常情况下,viewpager里面的内容是水平排列的。现在要做的第一步,就是将viewpager里面所有的view都显示在同一个位置,那么就需要自定义PageTransformer了。
既然ViewPager里面的View是水平排列的,那么只要将每个view的x轴坐标更改为:view的宽度乘以下标的负数,这样就排列在一起了,为了方便起见,还给view增加了一个透明度。代码如下:
public void transformPage(View page, float position) { //设置透明度 page.setAlpha(0.5f); //设置每个View在中间 page.setTranslationX((-page.getWidth() * position)); }来看看效果吧。
果然不出所料,效果和我们猜想的一样。
当当当当。。。下面就是见证奇迹的时刻了
是不是完全达到了我们的预期呢?然而还没有结束,因为我不管怎么滑动都是没有效果,这是为什么呢?因为没有处理划出去的那一页,加了一个下标判断,position<= 0的情况下就是在翻页(打log),接下来看代码:
public void transformPage(View page, float position) { if (position <= 0.0f) {//被滑动的那页 page.setTranslationX(0f); } else {//未被滑动的页 page.setTranslationX((-page.getWidth() * position)); //缩放比例 float scale = (page.getWidth() - mOffset * position) / (float) (page.getWidth()); page.setScaleX(scale); page.setScaleY(scale); page.setTranslationY(mOffset * position); }}
来看看效果:
第一张效果图中,在翻页的时候有一个旋转的角度,而我们前面实现的只是一个平滑的效果。在这里达到的效果就是从0°开始,随着翻页的进行,卡片旋转至-45°角,从上一步得到一个结论:position<= 0的情况下就是在翻页。看代码:
public void transformPage(View page, float position) { if (position <= 0.0f) {//被滑动的那页 page.setTranslationX(0f); //旋转角度 45° * -0.1 = -4.5° page.setRotation((45 * position)); } else { //缩放比例 float scale = (page.getWidth() - mScaleOffset * position) / (float) (page.getWidth()); page.setScaleX(scale); page.setScaleY(scale); page.setTranslationX((-page.getWidth() * position)); page.setTranslationY((mScaleOffset * <span class="hljs-number">0.8f</span>) * position); }}
运行起来看看效果
效果虽然是达到了,但是为什么会留一个角呢?想必聪明的你应该想明白了吧?里面的view移动的是一个屏幕的宽度,当我们平移的时候刚好移动到了屏幕的外面,当然没有问题。但是旋转却是以中心为原点进行喜欢转的,所以自然,就会漏出一个角了。 解决方法是view进行旋转的同时,将view的X轴进行减少,减少多少呢?从上图看,大概⅓就差不多能够移动到屏幕外面了。 上代码:
public void transformPage(View page, float position) { if (position <= 0.0f) {//被滑动的那页 position 是-下标~ 0 page.setTranslationX(0f); //旋转角度 45° * -0.1 = -4.5° page.setRotation((45 * position)); //X轴偏移 li: 300/3 * -0.1 = -10 page.setTranslationX((page.getWidth() / 3 * position)); } else { //缩放比例 float scale = (page.getWidth() - mScaleOffset * position) / (float) (page.getWidth()); page.setScaleX(scale); page.setScaleY(scale); page.setTranslationX((-page.getWidth() * position)); page.setTranslationY((mScaleOffset * <span class="hljs-number">0.8f</span>) * position); }}
看看,效果是不是更加的细腻了呢?
至此,整个效果就算是完成了,下面附上PageTransformer的代码
/** * 水平滑动的 */ public class CardPageTransformer implements ViewPager.PageTransformer { /** * 偏移量 */ private int mScaleOffset = 40; <span class="hljs-comment">/** * <span class="hljs-doctag">@param</span> mScaleOffset 缩放偏移量 单位 px */</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CardPageTransformer</span><span class="hljs-params">(<span class="hljs-keyword">int</span> mScaleOffset)</span> </span>{ <span class="hljs-keyword">this</span>.mScaleOffset = mScaleOffset; } <span class="hljs-meta">@SuppressLint</span>(<span class="hljs-string">"NewApi"</span>) <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">transformPage</span><span class="hljs-params">(View page, <span class="hljs-keyword">float</span> position)</span> </span>{ <span class="hljs-keyword">if</span> (position <= <span class="hljs-number">0.0f</span>) {<span class="hljs-comment">//被滑动的那页 position 是-下标~ 0</span> page.setTranslationX(<span class="hljs-number">0f</span>); <span class="hljs-comment">//旋转角度 45° * -0.1 = -4.5°</span> page.setRotation((<span class="hljs-number">45</span> * position)); <span class="hljs-comment">//X轴偏移 li: 300/3 * -0.1 = -10</span> page.setTranslationX((page.getWidth() / <span class="hljs-number">3</span> * position)); } <span class="hljs-keyword">else</span> { <span class="hljs-comment">//缩放比例</span> <span class="hljs-keyword">float</span> scale = (page.getWidth() - mScaleOffset * position) / (<span class="hljs-keyword">float</span>) (page.getWidth()); page.setScaleX(scale); page.setScaleY(scale); page.setTranslationX((-page.getWidth() * position)); page.setTranslationY((mScaleOffset * <span class="hljs-number">0.8f</span>) * position); } }}
上面的步骤有没有引起你的联想呢?例如:层叠在上面、左面、右面、上下滑动,再加个透明动画?哈哈 这些我都实现了,你可以直接引用我的library,使用我里面已经写好的PageTransformer。
来先看看效果
以下是使用方法
如果文中有什么不对的地方,欢迎指出!
源码地址 如果我的代码对你有帮组,请给我一个star
我的简书
来来扫下码,关注一下吧,或者微信搜索AndroidRookie
AndroidRookie </div> </div>转自:https://www.jianshu.com/p/1cb7cd31fa65