Android ViewPager实现动画切换效果

Android ViewPager实现动画切换效果,第1张

概述概述ViewPager是Android开发中使用场景非常频繁的控件,单一的动画效果切换已经越来越不能满足追求个性化的应用中。而ViewPager自身也带有一个接口来处理页面间的动画切换,那就是setPageTransformer。下面我们通过

概述

VIEwPager是AndroID开发中使用场景非常频繁的控件,单一的动画效果切换已经越来越不能满足追求个性化的应用中。而VIEwPager自身也带有一个接口来处理页面间的动画切换,那就是setPagetransformer。下面我们通过代码来学习动画效果的切换。

实现简单动画切换

代码如下:

1.布局文件

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:ID="@+ID/vIEw_pager_Box"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  androID:orIEntation="horizontal" >  <androID.support.v4.vIEw.VIEwPager    androID:ID="@+ID/vIEwpager"    androID:layout_margin="10dp"    androID:layout_wIDth="wrap_content"    androID:layout_height="120dp" /></linearLayout>

MainActivity 中相关 java 代码

import androID.app.Activity;import androID.os.Bundle;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.ImageVIEw.ScaleType;public class MainActivity extends Activity {  private VIEwPager vIEwPager;  private int[] imageIDs = new int[]{R.drawable.pic1,R.drawable.pic2,R.drawable.pic3,R.drawable.pic4,R.drawable.pic5,};  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    vIEwPager = (VIEwPager) findVIEwByID(R.ID.vIEwpager);    vIEwPager.setoffscreenPagelimit(3); //设置内存中预加载页面数    vIEwPager.setPagetransformer(true,new DepthPagetransformer()); //设置页面切换过渡动画    vIEwPager.setAdapter(new PagerAdapter() {      @OverrIDe      public boolean isVIEwFromObject(VIEw vIEw,Object object) {        return vIEw == object;      }      @OverrIDe      public int getCount() {        return imageIDs.length;      }      @OverrIDe      public Object instantiateItem(VIEwGroup container,int position) {        ImageVIEw imageVIEw = new ImageVIEw(MainActivity.this);        imageVIEw.setScaleType(ScaleType.CENTER_CROP);        imageVIEw.setimageResource(imageIDs[position]);        imageVIEw.setTag(position); //设置标记        container.addVIEw(imageVIEw);        return imageVIEw;      }      @OverrIDe      public voID destroyItem(VIEwGroup container,int position,Object object) {        container.removeVIEw((VIEw)object);      }    });  }}

3.控制切换动画的类DepthPagetransformer的代码

import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.VIEw;public class DepthPagetransformer implements VIEwPager.Pagetransformer {  private static final float MIN_SCALE = 0.75f;  @OverrIDe  public voID transformPage(VIEw vIEw,float position) {    androID.util.Log.i("yuminfeng","====vIEw:" + vIEw.getTag()  + ",position:" + position);    int pageWIDth = vIEw.getWIDth();    if (position < -1) { // [-Infinity,-1)       // This page is way off-screen to the left.      vIEw.setAlpha(0);    } else if (position <= 0) { // [-1,0]      // Use the default slIDe Transition when moving to the left page      vIEw.setAlpha(1);      vIEw.setTranslationX(0);      vIEw.setScaleX(1);      vIEw.setScaleY(1);    } else if (position <= 1) { // (0,1]      // Fade the page out.      vIEw.setAlpha(1 - position);      // Counteract the default slIDe Transition      vIEw.setTranslationX(pageWIDth * -position);      // Scale the page down (between MIN_SCALE and 1)      float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));      vIEw.setScaleX(scaleFactor);      vIEw.setScaleY(scaleFactor);    } else { // (1,+Infinity]      // This page is way off-screen to the right.      vIEw.setAlpha(0);    }  }}

上面的代码十分简单,仅仅只是VIEwPager的初始化配置,然后通过setPagetransformer设置页面切换动画。有一个细节还需要注意,设置setoffscreenPagelimit(3),表示内存中预加载页面为3,这三个页面是不可见的。如果加上当前显示的页面,总共初始化了4个页面。不设置的话,系统使用默认的预加载的页数为1。
第一次启动应用后,我们通过在DepthPagetransformer类中记录的日志可以看到,如下:

总共初始化了4个vIEw,其中当前对用户可见vIEw的位置为0,其余都是不可见。所以当position=0时,表示当前的页面。

我们继续 *** 作并向左滑动一页,日志如下:

由此可以看到,之前的vIEw的位置变为-1,它的右边的vIEw位置为0,变成可见。
继续滑动至最后一页后:

我们看到最后一页的vIEw已经展现在用户面前,位置为0,而其他页面位置都是为负,表示所有页面都滑至左边。这时我们注意的话,可以发现vIEw:0,不在日志信息中,难道它没有被初始化?其实它已经被系统回收了,通过Adapter中destroyItem方法。因为我们之前设置VIEwPager中预加载的页数限制为3,系统中最多的存在4个vIEw,所以vIEw:0被回收。

从上面的分析我们可以知道,当vIEw的position处于[-1,1]时,该vIEw能够被用户所见,其他位置便不可见。而Pagetransformer的接口中,真是利用了这个特点,根据vIEw的position来对它进行缩放,旋转等动画 *** 作。我们继续分析DepthPagetransformer类:
当 position < -1,即[-Infinity,-1) 时:
vIEw处于左边不可见中,这里vIEw.setAlpha(0); 表示完全透明。
当-1 <= position <= 0 时,该vIEw处于可见区域,:
1.如果vIEw向左滑动,表示当前vIEw逐渐滑出可见区域
2.如果vIEw向右滑动,表示左边的vIEw逐渐划入当前可见区域。
vIEw.setAlpha(1),设置透明度,表示完全不透明。
vIEw.setTranslationX(0),表示设置vIEw相对于左侧位置的水平位置,距离左边的距离。
vIEw.setScaleX(1)和vIEw.setScaleY(1),表示vIEw的x,y轴不进行缩放。
当0 < position <= 1 时,该vIEw处于可见区域:
1.如果vIEw向右滑动,表示当前vIEw逐渐滑出可见区域。
2.如果vIEw向左滑动,表示右边的vIEw逐渐滑入可见区域。
vIEw.setAlpha(1 - position),根据vIEw滑动的位置,设置vIEw的透明度。position 越接近于0,表明vIEw面对用户显示的越多,所以就越不透明。
vIEw.setTranslationX(pageWIDth * -position),根据vIEw滑动的位置,设置vIEw相对于左侧位置的水平位置,当position = 0 时,vIEw完全显示,这时相对左边为0,当 position = 1 时,vIEw完全不可见,这时相对左边为vIEw的宽度。
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
vIEw.setScaleX(scaleFactor);
vIEw.setScaleY(scaleFactor);
根据vIEw的position,设置vIEw的缩放大小。当 position,越大时,越远离用户界面,于是越不可见。
当1< position 时,即(1,+Infinity]时:
vIEw.setAlpha(0),设置完全透明不可见。

上述代码执行效果如下:

我们还可以定制其他的动画效果,实现原理和上面一样,这里就不一一列出来了。

实现广告轮播效果图

如图:

实现上面的效果图,只需要对上面的代码进行一些修改即可:

想要在屏幕上出现多个页面,我们需要设置属性:androID:clipChildren=”false”,该属性的意思是在VIEw进行绘制的时候,不去裁切它们的显示范围,即不限制vIEw的显示范围。
我们修改布局文件,如下:

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:ID="@+ID/vIEw_pager_Box"  androID:layout_wIDth="match_parent"  androID:layout_height="160dp"  androID:gravity="center"  androID:clipChildren="false"  androID:orIEntation="horizontal" >  <androID.support.v4.vIEw.VIEwPager    androID:ID="@+ID/vIEwpager"    androID:layout_wIDth="match_parent"    androID:layout_margin="30dp"    androID:layout_height="120dp" /></linearLayout>

在VIEwPager的外面控件中设置了androID:clipChildren=”false”,然后设置vIEwpager中androID:layout_margin属性,留出间距,方便显示左右两边的图片。后面我们还要java代码设置vIEwpager的属性,如:
vIEwPager.setPagemargin(40); //设置页面间间距
这样可以让页面之间存在一定的间隔。最后,我们通过setPagetransformer方法设置自己定义的动画即可,与上面一致。
该效果的动画类代码:

import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.VIEw;public class AlphaScaletransformer implements VIEwPager.Pagetransformer {  private static final float DEFAulT_MIN_Alpha = 0.5f;  private float mMinAlpha = DEFAulT_MIN_Alpha;  private static final float DEFAulT_MIN_SCALE = 0.85f;  private float mMinScale = DEFAulT_MIN_SCALE;  public static final float DEFAulT_CENTER = 0.5f;  @OverrIDe  public voID transformPage(VIEw vIEw,float position) {    int pageWIDth = vIEw.getWIDth();    int pageHeight = vIEw.getHeight();    vIEw.setScaleX(0.999f);// Hack    vIEw.setPivotY(pageHeight / 2);    vIEw.setPivotX(pageWIDth / 2);    if (position < -1) { // [-Infinity,-1)      vIEw.setAlpha(mMinAlpha);      vIEw.setScaleX(mMinScale);      vIEw.setScaleY(mMinScale);      vIEw.setPivotX(pageWIDth);    } else if (position <= 1) { // [-1,1]      if (position < 0) // [0,-1]      { // [1,min]        float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position);        float scaleFactor = (1 + position) * (1 - mMinScale) + mMinScale;        vIEw.setAlpha(factor);        vIEw.setScaleX(scaleFactor);        vIEw.setScaleY(scaleFactor);        vIEw.setPivotX(pageWIDth * (DEFAulT_CENTER + (DEFAulT_CENTER * -position)));      } else// [1,0]      {        // [min,1]        float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);        float scaleFactor = (1 - position) * (1 - mMinScale) + mMinScale;        vIEw.setAlpha(factor);        vIEw.setScaleX(scaleFactor);        vIEw.setScaleY(scaleFactor);        vIEw.setPivotX(pageWIDth * ((1 - position) * DEFAulT_CENTER));      }    } else { // (1,+Infinity]      vIEw.setAlpha(mMinAlpha);      vIEw.setPivotX(0);      vIEw.setScaleX(mMinScale);      vIEw.setScaleY(mMinScale);    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android ViewPager实现动画切换效果全部内容,希望文章能够帮你解决Android ViewPager实现动画切换效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147357.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存