当前位置: 移动技术网 > 移动技术>移动开发>Android > Android控件ViewPager实现带有动画的引导页

Android控件ViewPager实现带有动画的引导页

2019年07月24日  | 移动技术网移动技术  | 我要评论

viewpager实现带有动画的引导页,供大家参考,具体内容如下

好了,又到我们学习基础控件的时候了,其实引导页很简单,就是五张图片而已

一、viewpager实现传统的引导页

传统的viewpager实现引导页和listview是一样道理的,只是把listview的item换成图片,把baseadapter换成pageradapter,我们先来看下传统引导页的效果图

步骤一:编写xml文件

既然用到的是viewpager,那么xml文件就必须要有viewpager,细心的你,可能会发现最后一页还有个按钮的出现,没错,xml文件中也要有个按钮

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <android.support.v4.view.viewpager
    android:id="@+id/vp_guide"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

  <button
    android:id="@+id/bt_main"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignparentbottom="true"
    android:layout_centerinparent="true"
    android:layout_marginbottom="50dp"
    android:background="@color/colorprimary"
    android:padding="6dp"
    android:text="立即开启"
    android:textcolor="#fff"
    android:textsize="16dp"
    android:visibility="gone" />
</relativelayout>

步骤二:编写adapter

开头也说了,viewpager其实就和listview一样的,需要一个adapter,那么就从adapter入手。google提供了一个专门适配viewpager的adapter——pageradapter

public class guideadapter extends pageradapter {
  private list<view> views;
  private context context;

  public guideadapter(list<view> views, context context) {
    this.context = context;
    this.views = views;
  }

  public object instantiateitem(view container, int position) {
    ((viewpager) container).addview(views.get(position));
    return views.get(position);
  }

  public void destroyitem(view container, int position, object object) {
    ((viewpager) container).removeview(views.get(position));
  }

  public int getcount() {
    return views.size();
  }

  public boolean isviewfromobject(view arg0, object arg1) {
    return (arg0 == arg1);
  }
}

基本viewpager的adapter都是这么写的,就是往viewpager中添加list传过来的view和删除list传过来的view,可以说是每个viewpager的模板

步骤三:编写activity

我们找到对应的viewpager,然后设置adapter,代码中的initviews、initlistener、initdata是按顺序执行下去的,这段代码不难,很容易看懂

public class guideactivity extends baseactivity implements viewpager.onpagechangelistener {

  private viewpager vp_guide;
  private int[] imgid = {r.drawable.guide_center_1, r.drawable.guide_center_2, r.drawable.guide_center_3,
      r.drawable.guide_center_4, r.drawable.guide_center_5};
  private list<view> mimageviews;
  private guideadapter adapter;
  private button bt_main;

  @override
  public void initviews() {
    setcontentview(r.layout.activity_guide);
    vp_guide = (viewpager) findviewbyid(r.id.vp_guide);
    bt_main = (button) findviewbyid(r.id.bt_main);
  }

  @override
  public void initlistener() {
    bt_main.setonclicklistener(this);
    vp_guide.setonpagechangelistener(this);
  }

  @override
  public void initdata() {
    //初始化引导资源
    mimageviews = new arraylist<>();
    for (int i = 0; i < imgid.length; i++) {
      imageview imageview = new imageview(this);
      imageview.setscaletype(imageview.scaletype.center_crop);
      imageview.setimageresource(imgid[i]);
      mimageviews.add(imageview);
    }
    //设置引导页
    adapter = new guideadapter(mimageviews, this);
    vp_guide.setadapter(adapter);
  }

  @override
  public void processclick(view v) {
    switch (v.getid()) {
      //按钮点击事件,跳转到主页面
      case r.id.bt_main:
        intent intent = new intent(guideactivity.this, mainactivity.class);
        startactivity(intent);
        finish();
        break;
    }
  }

  @override
  public void onpagescrolled(int position, float positionoffset, int positionoffsetpixels) {
    if (position == imgid.length - 1) {
      //最后一个,实现动画浮现
      bt_main.setvisibility(view.visible);
      alphaanimation aa = new alphaanimation(0, 1f);
      aa.setduration(1000);
      bt_main.startanimation(aa);
    } else {
      bt_main.setvisibility(view.gone);
    }
  }

  @override
  public void onpageselected(int position) {

  }

  @override
  public void onpagescrollstatechanged(int state) {

  }
}

细心的你可能也发现了该引导页是没有状态栏的,所以我们需要设置其主题为状态栏透明

<activity
  android:name=".activity.guideactivity"
  android:theme="@android:style/theme.notitlebar.fullscreen"/>

特别注意:这里需要注意的是图片的大小问题,如果图片高清太大,可能会出现内存溢出的错误。

二、viewpager实现带有动画的引导页

带有动画的引导页编写步骤和传统是一模一样的,只不过给viewpager设置一个动画。google提供viewpager.setpagetransformer(boolean reversedrawingorder, pagetransformer transformer)方法来设置引导页的切换效果,这里先看google提供的切换demo

步骤一:编写pagetransformer

从上面效果看出,只是在引导页之间添加了一个动画而已,而google提供的pagetransformer就可以对当前位置的引导页进行操作,比如:设置透明度的变化,设置缩放的变化,就能实现切换的动画效果

public class depthpagetransformer implements viewpager.pagetransformer {

  private static final float min_scale = 0.75f;

  @override
  public void transformpage(view view, float position) {
    int pagewidth = view.getwidth();
    if (position < -1) {
      view.setalpha(0);
    } else if (position <= 0) {
      view.setalpha(1);
      view.settranslationx(0);
      view.setscalex(1);
      view.setscaley(1);
    } else if (position <= 1) {
      view.setalpha(1 - position);
      view.settranslationx(pagewidth * -position);
      float scalefactor = min_scale + (1 - min_scale) * (1 - math.abs(position));
      view.setscalex(scalefactor);
      view.setscaley(scalefactor);
    } else {
      view.setalpha(0);
    }
  }
}

步骤二:分析pagetransformer

从上面的代码中,可以知道在viewpager滑动的时候,会触发transformpage这个方法,并且会将当前的position和view传递过来,下面就是我们的对view的操作

① position

position < -1(即-无穷到-1):让引导页消失,透明度为0
position <= 0(即-1到0):让引导页出现
position <= 1(即0到1):让引导页根据position做动画
剩下else(即1到无穷):让引导页消失,透明度为0

② 图解position

原谅我画图不好看,不生动,如果还不理解的话可以自己打印log信息,把view和position都打印出来帮助理解

步骤三:使用pagetransformer

使用pagetransformer非常简单,只要通过viewpager设置即可

vp_guide.setpagetransformer(true, new depthpagetransformer());

三、其他动画的引导页的参考

google还为我们提供了另一个动画效果,看效果图

实现步骤其实和上面的步骤是一样的,具体我们来看pagetransformer的编写

public class zoomoutpagetransformer implements viewpager.pagetransformer {

  private static final float min_scale = 0.85f;
  private static final float min_alpha = 0.5f;

  @suppresslint("newapi")
  public void transformpage(view view, float position) {
    int pagewidth = view.getwidth();
    int pageheight = view.getheight();
    if (position < -1) {
      view.setalpha(0);
    } else if (position <= 1) {
      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);
      }
      view.setscalex(scalefactor);
      view.setscaley(scalefactor);
      view.setalpha(min_alpha + (scalefactor - min_scale) / (1 - min_scale) * (1 - min_alpha));
    } else {
      view.setalpha(0);
    }
  }
}

这里的原理就不分析了,和上面是一样的,只不过操作不同而已。除了google提供的demo之外,我们可以模仿谷歌的demo,编写出我们自己的动画效果

public class rotatedownpagetransformer implements viewpager.pagetransformer {

  private static final float rot_max = 20.0f;
  private float mrot;

  public void transformpage(view view, float position) {
    if (position < -1) {
      viewhelper.setrotation(view, 0);
    } else if (position <= 1) {
      //[-1,1]
      mrot = (rot_max * position);
      viewhelper.setpivotx(view, view.getmeasuredwidth() * 0.5f);
      viewhelper.setpivoty(view, view.getmeasuredheight());
      viewhelper.setrotation(view, mrot);
    } else {
      viewhelper.setrotation(view, 0);
    }
  }
}

效果如图

好了,今天基础控件就到这里了,如果不懂的话可以自己实践一下,然后用纸笔思考思考,你就会有收获的。我也是通过博客学习别人的博客,然后通过自己的方式,将学习的内容写出来。我们一起加油,后来者们

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网