Android属性动画1-----属性动画的简单使用

【Android属性动画1-----属性动画的简单使用】在Android开发过程中,最原始的2种动画分别为补间动画和帧动画,两者存在的弊端都非常明显,补间动画只能由肉眼观察到动画,然而却不能响应点击事件,因为容器并没有移动;帧动画因为需要大量的图片做基础,对内存也是非常大的消耗,因此在项目中都会尽量避免使用帧动画。
在API 3.0之后,出现了第3种动画属性动画,也是当前使用频率最高的动画类型,大部分App中的动画特效均为属性动画制作。
1、属性动画
属性动画解决了补间动画的弊端,容器随着动画的移动而移动,对于任意对象均可设置动画,常用的动画有ValueAnimator(值动画)、ObjectAnimator (对象动画),下面的都是这两个重要动画的辅助工具:PropertyValueHolder(多个动画同时执行)、AnimationSet(集合动画)、Interpolator (插值器)、TypeEvaluator(估值器)
(1)ObjectAnimator

//对象动画,但不局限于对象 ObjectAnimator oa = ObjectAnimator.ofFloat(iv_animation, "alpha",1.0f,0.4f); oa.setDuration(3000); //开启动画 oa.start();

(2)ValueAnimator
这是Android属性动画中最核心的类,通过设置数值完成平滑的匀速移动,通过设置监听得到当前的值,设置给View完成动画的移动。
//值动画 ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100); valueAnimator.setDuration(3000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //获取当前动态变化的值 int location = (int) animation.getAnimatedValue(); iv_animation.setX(location); iv_animation.setY(location); } }); //启动动画 valueAnimator.start();

通过设置addUpdateListener监听,可以使用getAnimatedValue获取当前移动的距离,设置View的x,y坐标。
除了上述的API之外,还可以设置重复的次数。
//设置重复的次数 valueAnimator.setRepeatCount(2); valueAnimator.setRepeatCount(ValueAnimator.RESTART);

(3)PropertyValueHolder
//多个动画同时进行 PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.3f); PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.5f); PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.5f); ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(iv_animation,holder1,holder2,holder3); objectAnimator.setDuration(3000); objectAnimator.start();

PropertyValueHolder是多个动画同时运行,是通过ObjectAnimatorofPropertyValuesHolder来实现,例如上例中,分别3个动画为:清晰度、X轴缩放为原来的一半、Y轴缩放为原来的一半。
和AnimationSet有什么区别呢?
AnimationSet同样也是集合动画,但是AnimationSet更加灵活,可以一起执行,也可以是顺序执行,执行完一个动画之后 就会执行下一个动画。
(4)AnimationSet
ObjectAnimator o1 = ObjectAnimator.ofFloat(iv_animation,"translationX",0f,500f); ObjectAnimator o2 = ObjectAnimator.ofFloat(iv_animation,"alpha",1.0f,0.5f); ObjectAnimator o3 = ObjectAnimator.ofFloat(iv_animation,"scaleX",1.0f,1.5f); AnimatorSet set = new AnimatorSet(); set.setDuration(3000); set.playSequentially(o1,o2,o3); set.start();

playSequentially就是按顺序执行,会依次执行完3个动画。
//链式调用 set.play(o3).with(o2).after(o1); set.play(o3).with(o2).before(o1);

通过链式调用,控制动画的播放顺序,在上述的链式中,就是设计的在o1动画完成之后(或者之前before),o2和o3会一起执行。
set.playTogether(o1,o2,o3);

使用playTogether就是实现了PropertyValueHolder的功能,能够实现多个动画的同时执行。
(5)TypeEvaluator(估值器)
对于ValueAnimationObjectAnimation来说,他们的状态变化是匀速的,等值地变化,因此对于想要实现加速度的效果,例如自由落体,单纯地使用这2种属性动画就比较难了,因此可以使用估值器来完成。
估值器可以自定义动画的变换规则,也可以改变运行轨迹,实现特殊的动画效果
//设计平抛效果 ValueAnimator animator = new ValueAnimator(); animator.setDuration(3000); //初始坐标为0 0 animator.setObjectValues(new PointF(0,0)); final PointF pointF = new PointF(); animator.setEvaluator(new TypeEvaluator() { @Override public Object evaluate(float fraction, Object startValue, Object endValue) { pointF.x = 100f * (fraction * 5); pointF.y = 0.5f * 98f * (fraction*5)*(fraction * 5); return pointF; } }); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //获取估值器中自定义好的对象 PointF location = (PointF) animation.getAnimatedValue(); iv_animation.setX(location.x); iv_animation.setY(location.y); } }); animator.start();

在使用ValueAnimator时,调用addUpdateListener,内部其实也有一个估值器,但是这个估值器是匀速的,通过getAnimatedValue可以得到其中的值,但是要想实现自由落体的效果,匀速的估值器是不可能实现的,平抛水平方向匀速,竖直方向自由落体,因此需要通过setEvaluator更改估值器,在x和y轴设置,返回Object对象,在getAnimatedValue中就可以得到这个PointF
(6)Interpolator 插值器
其实插值器和估值器是类似的,唯一的区别在于,估值器的算法需要自己编写,而插值器的算法是由API提供的,大概分为9种。
ValueAnimator v1 = new ValueAnimator(); v1.setDuration(3000); v1.setObjectValues(new PointF(0,0)); final PointF point = new PointF(); v1.setEvaluator(new TypeEvaluator() { @Override public Object evaluate(float fraction, Object startValue, Object endValue) { point.x = 100f * (fraction * 5); point.y = 0.5f * 98f * (fraction*5)*(fraction * 5); return point; } }); v1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //获取估值器中自定义好的对象 PointF location = (PointF) animation.getAnimatedValue(); iv_animation.setX(location.x); iv_animation.setY(location.y); } }); //加速度插值器 v1.setInterpolator(new AccelerateInterpolator(10)); v1.start();

AccelerateInterpolator:加速插值器,公式: y=t^(2f) (加速度参数. f越大,起始速度越慢,但是速度越来越快;刚开始速度很慢,但是瞬间就下落。)
v1.setInterpolator(new DecelerateInterpolator(5));

DecelerateInterpolator:减速插值器公式: y=1-(1-t)^(2f) (描述: 加速度参数. f越大,起始速度越快,但是速度越来越慢)
v1.setInterpolator(new AccelerateDecelerateInterpolator());

AccelerateDecelerateInterpolator:先加速后减速
v1.setInterpolator(new AnticipateInterpolator(tension:8));

AnticipateInterpolator:张力值,tension值越大,偏移量就越大,而且速度越快。
v1.setInterpolator(new AnticipateOvershootInterpolator(2,3));

public AnticipateOvershootInterpolator() { mTension = 2.0f * 1.5f; } public AnticipateOvershootInterpolator(float tension, float extraTension) { mTension = tension * extraTension; }

AnticipateOvershootInterpolator:张力插值器,类似于抛物线似的,tension和extraTension默认值是2和1.5,值越大,偏移量就越大,速度就越快。
v1.setInterpolator(new BounceInterpolator());

BounceInterpolator:弹跳插值器
v1.setInterpolator(new CycleInterpolator(2));

CycleInterpolator:周期插值器,可以设置动画重复的时间周期,类似于repeat
v1.setInterpolator(new LinearInterpolator());

LinearInterpolator:匀速插值器,这个会屏蔽之前自定义的估值器,而是匀速的完成平抛。
以上就是属性动画中最重要的动画及辅助器,最核心的ValueAnimator类,将会配合估值器和插值器实现多种类型的动画,包括现在的App中,尤其是直播类的App中,观众在发送礼物时,屏幕上会出现该礼物的动画效果,这就涉及到了属性动画的使用,在之后的章节中,将会详细介绍属性动画的高级使用,打造一个动画框架。

    推荐阅读