ViewPager动画详解

GitHub:lightSky

微博:    light_sky , 即时分享最新技术,欢迎关注


前言

前两天看到鲍永章分享的Great animations with PageTransformer以及农民伯伯分享的Create ViewPager transitions 文章,都是通过ViewPager来实现酷炫的动画,而现在的App中ViewPager的动画使用也非常的广泛。正好最近一直研究动画,那么就趁热打铁,分析一下相关的开源库吧。本篇文章介绍的ViewPager动画,可以分为两类,第一类是针对于ViewPager的界面滑动动画(这个是PageTransformer的真正用途),分析并比较了AndroidImageSlider和JazzyViewPager两种实现,第二类是对ViewPager中的内容进行动画处理,这个是这个是PageTransformer的巧妙应用,处理好了可以达到很棒的交互效果,示例是Yahoo天气的视差效果。


ViewPager动画的实现原理

从3.0开始,ViewPager开始支持自定义切换动画,暴露的接口为PageTransformer,因此只要实现PageTransformer接口和其唯一的方法transformPage(View view, float position)即可。

/**
   * A PageTransformer is invoked whenever a visible/attached page is scrolled.
   * This offers an opportunity for the application to apply a custom transformation
   * to the page views using animation properties.
   *
   * <p>As property animation is only supported as of Android 3.0 and forward,
   * setting a PageTransformer on a ViewPager on earlier platform versions will
   * be ignored.</p>
   */
  public interface PageTransformer {
      /**
       * Apply a property transformation to the given page.
       *
       * @param page Apply the transformation to this page
       * @param position Position of page relative to the current front-and-center
       *                 position of the pager. 0 is front and center. 1 is one full
       *                 page position to the right, and -1 is one page position to the left.
       */
      public void transformPage(View page, float position);
 }

  • 参数position
    给定界面的位置相对于屏幕中心的偏移量。在用户滑动界面的时候,是动态变化的。那么我们可以将position的值应用于setAlpha(), setTranslationX(), or setScaleY()方法,从而实现自定义的动画效果。
    另外在ViewPager滑动时,内存中存活的Page都会执行transformPage方法,在滑动过程中涉及到两个Page,当前页和下一页,而它们的position值是相反的(因为是相对运动,一个滑入一个滑出),比如,页面A向右滑动到屏幕一半,页面B也正好处于一半的位置,那么A和B的position为:0.5 和 -0.5
    position == 0 :当前界面位于屏幕中心的时候
    position == 1 :当前Page刚好滑出屏幕右侧
    position == -1 :当前Page刚好滑出屏幕左侧


AndroidImageSlider动画库解析

要说到动画库,肯定会想到代码家,没错,代码家也开源了一个ViewPager效果的库:AndroidImageSlider ,我们就来分析下这个库的实现。AndroidImageSlider除了基本的page动画外,也支持用户为Page内容添加自定义的动画,比如下面描述框的动画。


AndroidImageSlider兼容性的实现原理
因为API 11才开始支持PagerTransformer. 这里面修改了Android系统的ViewPager,名为ViewPagerEx,ViewPager里面有一段if逻辑判断是否在3.0以上使用PagerTransformer。因为PagerTransformer动画效果的实现依赖了PropertyViewAnim。但代码家的这个库使用NineOldAndroids实现了向3.0之前的兼容。因此就把这个if条件去掉了,其它部分都没变。

/**
 * @author daimajia : I just remove the if condition in setPageTransformer() to make it compatiable with Android 2.0+
 * of course, with the help of the NineOldDroid.
 * Thanks to JakeWharton.
 * http://github.com/JakeWharton/NineOldAndroids
 */


AndroidImageSlider的总体设计

  • BaseTransformer
    所有Transformer的基类,实现了ViewPagerEx.PageTransformer接口以及transformPage方法,并提供了onPreTransform(View view, float position)、onPostTransform(View view, float position)、onTransform(View view, float position);
    分别在transformPage前后调用,用来处理为每一次的执行动画前的准备和结束动作,比如还原所有的动画状态。

  • BaseAnimationInterface:
    ViewPagerEx执行Transformer动画的时候注入一些自己的动画。你需要实现该接口,然后实现以下4个方法,获取SlideView中的View,实现自己的动画。比如底部的DescriptionText动画DescriptionAnimation 出现时的动画就是onNextItemAppear中添加的,你可以点入,看下源码
    onPrepareCurrentItemLeaveScreen(View current)
    onPrepareNextItemShowInScreen(View next)
    onCurrentItemDisappear(View view)
    onNextItemAppear(View view)

而这4个方法的调用是在BaseTransformer中。BaseTransformer统一管理了Page滑动时的所有动画。为了获取这4个方法的调用时机,也是煞费苦心啊,先说下思路:
因为ViewPager滑动的时候transformPage方法是实时调用的,这里获取最初两次调用时传入的position进行比较。通过一个HashMap<view, arraylist>来维护不同pageView的多个position。但这里为了优化,只取前两个position做比较。
先判断起始滑动的方向&#

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值