RecyclerView动画:属性动画

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014749572/article/details/98782365

        通过RecyclerView的实现展开动画动画的时候,首先想到的是通过原生的方法notifyItemRangeChanged来实现。但是android并没有提供很多Api,让使用者来自定义动画。

        为了更好的实现动画的自定义,必须查看RecyclerView动画的实现机制。在此基础上才能够有机会hook动画机制,从而实现更好的自定义。目前实现了动画的差值器、展开距离、动画时间的自定义。

        从postAnimationRunner方法开始,RecyclerView的Item动画就真正的开始了。

        通过postOnAnimation方法在主线程的handler中post了一个Runnable。这个Runnable中就是就是整个Item动画中心。所有Item的move、remove、add、change动画都是这里开始装载、开始的。

      在runPendingAnimations方法中,我们来关注下change的动画。change动画是通过DefaultItemAnimator.ChangeInfo类来封装的,并通过列表(ArrayList<DefaultItemAnimator.ChangeInfo> mPendingChanges)来管理所有待动画的item项。ChangeInfo的添加逻辑逻辑就不在这里展开了感兴趣的同学可以查看RecyclerView源码中的dispatchLayoutStep3()方法。这里必须提出一个RecyclerView的坑,当展开的item过多时(高度过高),就没有了展开动画。

       因为RecyclerView是自身height来决定加载Item数量的,所以当添加的item项的总高度大于RecyclerView高度时,这个时候之前的item项会从父View中移除。导致的结果是没item进行change动画。RecyclerView展开动画的实质就是对被展开item项下面的所有item进行translate动画。既然item已经被移除了界面,那动画肯定就没了。

      下面将会请出今天的主角ViewPropertyAnimator。在animateChangeImpl方法中对itemView进行了动画的设置,其中设置了动画的时间,translateX,translateY,alpha等属性的设置。(注意这里可能会涉及到连个View的动画,这里不做展开)

      重头戏终于要开始了。下面来看看属性动画是怎么来改变View属性从而实现动画的呢?是什么来驱动动画的呢?首先我们来看看ViewPropertyAnimator的startAnimation方法。通过源码分析可知,方法中主要是对ValueAnimator进行设置,可知真正的动画是通过ValueAnimator来实现的。

       ValueAnimator的start方法也是暗藏玄机。其中有一方法addAnimationCallback。方法中通过AnimationHandler对象实现了属性动画的注册。

        AnimationHandler可以说是来头不小,它可以说是管理者所有的属性动画。通过AnimationHandler的统一管理能够确保所有的属性动画在主线程中自信,同时确保了多个动画能够在相同的时间去修改属性,实现动画时间的统一性。

       那么驱动AnimationHandler的动力是什么呢?说道动力我们就不得不请出UI届扛把子Choreographer。对于这位老大哥,大家应该都有所耳闻。在android上层的UI绘制中,每次都是他响应UI绘制请求。大家都知道在其doFrame方法中有三部曲,分别是measureHierarchy、performLayout、performDraw。

      在演奏三部曲之前,Choreographer会先去执行动画,而动画的实质就是不同的时间点对View对想设置不同的属性,然后在绘制到屏幕上。实现就是在Choreographer通过AnimationHandler,在每次绘制请求到来的时候回调AnimationHandler中注册的ValueAnimator。

      首先看看回调AnimationHandler的内容。

上述方法比较简单,主要是回调了doAnimationFrame方法。在doAnimationFrame中主要也是回调注册的ValueAnimator对象。

       在doAnimationFrame方法中主要是基于基于时间线计算对应的值,并回调注册的监听。本例中注册的是ViewPropertyAnimator对象。下面是截取的部分源码。感兴趣的同学可以看看源码。这里不再赘述。

ValueAnimator中的回调:

ViewPropertyAnimator中的回调:

 

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页