在上一篇博客中,我们简单了解了在Android中的动画特效,小伙伴们是不是意犹未尽呀。还没有看的猛戳这里:Android动画之旅一开篇动画简介
本篇博客,将和大家一起来分析Android中的四大动画,准备好了吗?GO~ GO~ GO~
Android动画大致可以分为以下四类:
(1)逐帧动画(Frame Animation)
(2)补间动画(Tween Animation)
(3)属性动画(Property Animation)
(4)布局动画(Layout Animation)
在Android3.0(即API Level11)以前,Android仅支持2种动画:分别是Frame Animation(逐帧动画)和Tween Animation(补间动画),在3.0之后Android支持了一种新的动画系统,称为:Property Animation(属性动画)。
首先,我们来分析逐帧动画(Frame Animation):
相信大家都知道皮影戏吧?简单的说就是人工操作一个皮质小人物来上演一场假人戏。如果感觉这个抽象的话,那大家肯定都看过电影吧,其实现在的电影院播放电影不能深刻体现我们的主题,在80年代的时候,那个时候播放电影都是在电影机上放上拍好的录像带,然后一轴一轴的播放出来。电影机连续的转动带动录像带,在荧屏上展现出连续的精彩画面。其实逐帧动画就好比播放电影,是将电影一帧一帧的展现出来,将连续的动作拆分成几个甚至几百个小动作。其实现实生活中的例子很多,比如我们现在看到的Gif动态图片,原理也是如此。
在Android中定义逐帧动画很简单,大概分为两种实现方式:
(1)定义xml的drawable资源就可以轻松实现,下面来看具体的实现步骤:
定义Animation-list:
1.因为在res文件夹下,Android工程默认是没有动画文件夹的。那么需要我们手动来创建,名字为:anim。
2.然后在anim文件夹下,创建一个animation-list的xml资源文件,命名符合规则任意即可。
3.在animation-list的根元素可以指定android:oneshot属性。该属性指定是否仅播放一次。在item中有两个属性值,分别是drawable、duration。android:drawable指定需要播放的每一帧图片,android:duration顾名思义,就是指定播放所需要的时间。
以上实现完成之后,我们就可以在XML文件中使用该动画文件。一般情况下,在Android中都会将该动画文件作为ImageView的background。
然后在代码中,通过获取ImageView的background,然后强转为AnimationDrawable就可以得到该动画Drawable资源,该类对象包含了start()和stop()方法,即播放和暂停。单纯的获取到AnimationDrawable是不会自动播放的,所以还需要我们手动调用start()方法来开始动画。那么这样一个简单的逐帧动画效果就完成了。
(2)在Java代码中实现:这种方式也很简单,在代码中手动创建AnimationDrawable对象,然后调用它的addFrame(Drawable frame, int duration)方法将一帧帧drawable即图片添加进去,同时第二个参数也设置了播放该帧所需要的时间。小伙伴们可以亲自试下,效果本质是一样的。
应用场景:Loading加载,例如QQ JD的loading等等都是如此。
介绍完了逐帧动画,下面我们一起来分析下第二种Android动画即补间动画。
补间动画也成为 Tween Animation。上面介绍的逐帧动画是需要一帧帧的去指定然后播放出来。补间动画可以理解为只需指定开始、结束的“关键帧“,而变化中的其他帧由系统来计算,不必自己一帧帧的去定义。
补间动画在Android中分为四类:
(1)位移动画(TranslateAnimation)
(2)透明度动画(AlphaAnimation)
(3)旋转动画(RotateAnimation)
(4)缩放动画(ScaleAnimation)
四种动画,其实使用方式都是大同小异的,下面我们以位移动画来简单介绍在Android中如何实现补间动画的效果。
Android使用Animation代表抽象动画,并在在java代码中创建Animation类对象。我们一般都会采取动画资源文件来定义动画,即在anim中定义动画资源文件。
在上图的代码中,我们定义了一个set的根元素,set代表了一组动画集合,不过指定一个动画也是可以的。在set个元素中,我们指定了两个属性元素:
android:fillAfter
android:interpolator
第一个属性是一个boolean类型的值,代表了当动画完成后是否保留在动画结束。设置true即保留,反之,则不保留。
第二个属性比较重要,Android中叫它为插值器。它代表了一个动画附加的渲染效果,简单来说就是控制动画速度,下面我会简单解释下该属性对应的几种效果:
1. AccelerateInterpolator 加速插值器
2. AccelerateDecelerateInterpolator 加速减速插值器
3. LinearInterpolator 线性插值器
4. BounceInterpolator 弹跳插值器
5. AnticipateInterpolator 回荡秋千插值器
6. AnticipateOvershootInterpolator
7. CycleInterpolator 正弦周期变化插值器
8. OvershootInterpolator
具体效果可以参考Google官方的API Demo,此处也可以参考该博客进行细致了解:http://www.cnblogs.com/mengdd/p/3346003.html
定义好anim文件后,我们可以通过AnimationUtils工具类来加载它们,加载成功后返回一个Animation。然后就可以通过View的startAnimation(anim)开始执行动画了。
Animation anim = AnimationUtils.loadAnimation(this, R.anim.translation); //在代码中设置动画结束后保留结束状态,,如果xml中设置了就不需要在此处设置。 anim.setFillAfter(true); //在代码中设置插值效果
anim.setInterpolator(new CycleInterpolatorCycleInterpolator()); view. startAnimation(anim);
其他的动画和位移动画的使用方式几乎相同,此处就不在一一列出,有兴趣的小伙伴们可以亲自体验一下。
说完了补间动画,下面我们就要说下大名鼎鼎的属性动画了。
属性动画,也称为Property Animation。是在Android 3.0中引进的,它可以直接更改我们对象的属性。在上面提到的补间动画(Tween Animation)中,只是更改View的绘画效果而View的真实属性是不改变的。假设你用Tween动画将一个Button从左边移到右边,无论你怎么点击移动后的Button,都不会有反应。而当你点击移动前Button的位置时才有反应,因为Button的位置属性是没有改变的。而属性动画(Property Animation)则可以直接改变View对象的属性值,这样可以让我们减少代码的编写难度,同时做出绚丽的动画效果。
属性动画分为两个部分:
(1)数值动画(ValueAnimator):包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。
(2)对象动画(ObjectAnimator):继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件:
1.对象应该有一个setter函数。
2.如下面的例子,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了一个值的话,那么会假定为目的值(目的值就是说假设是在X轴移动,就是从当前位置移动到的位置的数值),属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法,即getXXX()。
3.如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
如果以上条件不能满足,那么我们就只能用ObjectAnimator的父类ValueAnimator来获取数值并自己实现动画了。
从上面的图中,我们看到创建ObjectAnimator对象时使用了ObjectAnimator类并调用其ofFloat()方法用来做移动,也因此我们可以知道,该类使用了工厂模式来设计ofXXX方法。ObjectAnimator除了提供ofFloat以外,还提供了一些其他的ofXXX方法:
从图中可以看到Float、Argb、Object、Int、MultiInt、PropertyValuesHolder等等一些重载的方法,有兴趣的小伙伴可以去尝试一下。
在此说下ofPropertyValuesHolder这个方法,此方法是将多个PropertyValuesHolder对象集成在一起,也就是将多个动画合并在一起执行,也就是我们所谓的动画集:
可以看到,PropertyValuesHolder对象也和ObjectAnimator一样提供了一些ofXXX的方法,使用ObjectAnimator的ofPropertyValuesHolder将多个PropertyValuesHolder合并在一起来完成整个动画效果,其他的方法此处就不再过多展示。
ObjectAnimator类还提供了addListener(AnimatorListener listener)方法,该方法用来监听动画的执行过程。
使用AnimatorListener需要实现它其中的4个方法:
(1)onAnimationStart:动画开始时回调。
(2)onAnimationEnd:动画结束时回调。
(3)onAnimationCancel:取消动画时回调。
(4)onAnimationRepeat:动画重复执行时回调。
以上就是动画的监听回调方法,这时候有的小伙伴就说,如果我只想实现其中的一个方法怎么办?答案肯定是没问题,这个时候我们可以使用另一种实现方式:
用AnimatorListenerAdapter这个类我们就可以实现自己想要实现的回调方法啦!是不是很简单耶~
属性动画中还有一个重要的类:AnimationSet。顾名思义,该类可以组合多个动画共同工作。在上面我们说过一个组合动画的方式,相信大家都还记得吧。忘记的往上看吧哈哈。
使用AnimationSet,可以将多个动画集成在一起播放,AnimationSet提供了主要的几个方法:
从上面的程序可以看到,主要有以下几个方法:
(1)play:播放动画。
(2)with:和某个动画一起播放。
(3)before:在某个动画之前播放。
(4)after:在某个动画之后播放。
(5)playTogether:将多个动画同时播放。
(6)playSequentially:将多个动画按顺序播放。
以上方法是用相对来说还是比较简单的,就不再多说了,大家可以试着写一下就会很明白的。
最后还有一个动画类ViewPropertyAnimator,即对一个View同时改变多种属性,非常推荐用这种。该类对多属性动画进行了优化,会合并一些invalidate()来减少刷新视图。而且使用起来非常简便,但是要求API LEVEL 12,即Android 3.1以上。仅需要一行代码即可完成水平、竖直移动。
实现布局动画需要使用LayoutAnimationController类完成:
上图代码中,我们使用LayoutAnimationController类来创建了一个布局动画,很简单,只需要我们将Animation作为LayoutAnimationController类的构造方法参数传入即可。LayoutAnimationController实例的setOrder方法用来指定播放顺序,最后使用一个ListView方法的setLayoutAnimation方法,将动画绑定的ListView上。
我们分别从Android动画的分类来一一详细介绍了Android中的几大动画,以及使用的方法,相信小伙伴们对于Android的动画又有了全新的认识吧!下一篇博客,我将带领大家一起用Android属性动画系统的完成一个小小的实战案例:Android动画之旅 一 仿简聊App动画菜单。
好啦,本篇博客就到这里啦,有错误的地方还请大家积极提出,小伙伴们赶紧拍砖啦~~~