文章是对HenCoder Android 自定义 View 1-6:属性动画 Property Animation(上手篇)的总结,读者可以直接通过链接看 HenCoder 的这篇文章。
帧动画:即Drawable动画,是通过多张动画依次播放来达到动画的效果,使用AnimationDrawable类来完成,效果比较简单
View动画:即补间动画,这种动画效果没有改变View的实际响应位置,而且这种动画只能作用于View对象
属性动画:是通过改变类属性来达到动画的效果。类可以是View,也可以是别的任何类,系统通过调用类的set方法来改变属性,达到动画的效果。和View动画不同的是,属性动画除了突破了View的限制,而且改变了被作用对象的响应位置。
作用比较简单,只有最基本的几种动画效果:透明度、平移、缩放、旋转和动画集合,分别对应AlphaAnimation、TranslatenAnimation、ScaleAnimation、RotateAnimation、AnimationSet
由于属性动画是通过设置类的属性值来达到动画的效果,即通过set方法设置属性,通过get
方法获取属性,(该属性必须有set、get
方法)所以属性动画能够实现的效果就比较多,在实际使用中大部分都是使用属性动画,系统提供的属性动画api 从简单到复杂,依次为ViewPropertyAnimator、ObjectAnimator、ValueAnimator
ViewPropertyAnimator 使用起来最简单,比如:
ImageView image = (ImageView) findViewById(R.id.image);
image.animate().alpha(0f).translationX(500);
这样就可以让image变透明同时移动500
ObjectAnimator的使用相对于ViewPropertyAnimator复杂一点,但是更加灵活一点,使用方法:
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "translationX", 100);
animator.setDuration(500);
animator.start();
ObjectAnimator有很多ofxxx 方法,意思是我们设置属性的类型,比如上面的例子,我们要改变的是image这个对象的 translationX 这个属性,而这个属性是Folat 类型,所以我们需要使用ofFloat类型。
ofxxx方法的第一个参数是要作用的对象,第二个方法是要设置的属性,是字符串形式,如上方法,当调用的时候系统会拼接这个字符串,拼接成set方法去设置对象的translationX属性.
第三个参数是设置参数的值,后面还可以填入更多的数值,当填入一个数值的时候表示属性的目标值;两个的时候第一个表示起始值,第二个表示目标值;三个的时候第一个表示起始值,最后一个表示目标值,中间的都是转折点。
ValueAnimator是ObjectAnimator的父类,实际上ViewPropertyAnimator和ObjectAnimator都是使用ValueAnimator来实现的,ValueAnimator是最基础的轮子,所以在使用上ValueAnimator是最灵活的,同时它也是最难用的,大多数情况下我们是使用不到ValueAnimator的,上面两个Animator就满足需求了。
1:设置动画时长
2:设置速度设置器(Interpolator )
3:设置监听器
这个比较简单,直接调用 api 就能设置
image.animate()
.alpha(0f)
.translationX(500)
.setDuration(1000);
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "translationX", 100);
animator.setDuration(500);
animator.start();
速度设置器即Interpolator ,速度设置器的作用是设定动画从开始到结束的速度模型,就是这个过程的速度是先快后慢,还是先慢后快,还是匀速。系统提供了很多速度设置器,如果不设置,默认的是先快慢,速度慢慢减速到0然后停止。
AccelerateDecelerateInterpolator
先加速再减速(默认的)
LinearInterpolator
匀速
AccelerateInterpolator
持续加速
DecelerateInterpolator
持续减速直到 0
AnticipateInterpolator
先回拉一下再进行正常动画轨迹
OvershootInterpolator
动画会超过目标值一些,然后再弹回来
AnticipateOvershootInterpolator
上面这两个的结合版:开始前回拉,最后超过一些然后回弹
BounceInterpolator
在目标值处弹跳。有点像玻璃球掉在地板上的效果
CycleInterpolator
这个也是一个正弦 / 余弦曲线,不过它和 AccelerateDecelerateInterpolator 的区别是,它可以自定义曲线的周期
PathInterpolator
自定义动画完成度 / 时间完成度曲线
5.0新加入:
FastOutLinearInInterpolator
加速运动
FastOutSlowInInterpolator
先加速再减速
LinearOutSlowInInterpolator
持续减速
给动画设置监听器,可以监听动画的执行开始、结束,执行的整个过程,在这些时机可以做一些事情
ViewPropertyAnimator
使用 setListener()
和 setUpdateListener()
设置监听器,set[Update]Listener(null)
填 null
值来移除
而 ObjectAnimator
则是用 addListener()
和 addUpdateListener()
来添加一个或多个监听器,移除监听器则是通过remove[Update]Listener()
来指定移除对象。
其中updateListener
可监听动画的实时变化,Listener
可以监听动画的开始、结束或者动画重复等时机。
ObjectAnimator
是支持 pause()
方法的,所以它是可以添加 addPauseListener
;而ViewPropertyAnimator
中有withStartAction()
和 withEndAction()
方法,可以设置一次性的动画开始或结束的监听。
因为在ObjectAnimator中设置动画的方法都是 ofxxx ,当我们在做属性动画的时候,有时系统提供的不满足自己的要求,或者自定义View的时候没有相应的属性,这只就要用到 TypeEvaluator 了,可以通过自定义TypeEvaluator,然后使用 ofObject() 方法来创建 Animator , 然后将自定义的 TypeEvaluator 作为参数传入。
同时改变动画的多个属性,在ViewPropertyAnimator中直接流式调用 api 即可,但是在ObjectAnimator中需要使用 PropertyValuesHolder 才能完成。
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 0,1);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 0,1);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 0,1);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(image, holder1, holder2, holder3);
animator.setDuration(1000);
animator.start();
上面的 PropertyValuesHolder 用来多个动画属性同时改变,但是当我们需要多个属性改变需要一定顺序的时候就要用到 AnimatorSet
ObjectAnimator translate = ObjectAnimator.ofFloat(image, "translationX", 500);
translate.setDuration(500);
ObjectAnimator scale = ObjectAnimator.ofFloat(image, "scaleX", 0,1);
scale.setDuration(1000);
AnimatorSet set = new AnimatorSet();
//两个动画顺序执行
set.playSequentially(translate,scale);
set.start();
除此之外,还有更多的先后顺序的 api
set.play(animator1).with(animator2);
set.play(animator1).before(animator2);
set.play(animator1).after(animator2);
set.start();