您的位置:首页 > 产品设计 > UI/UE

Android属性动画ValueAnimator快速上手

2016-09-23 09:57 344 查看

用处及部分原理

Android在API11中新增ValueAnimator类用于实现更多屌炸天的动画效果,其主要核心逻辑在于:

根据开发者设置的动画总时间调用Interpolator取得一个动画执行的效率值A,再调用TypeEvaluator中的evaluate方法传入值A返回计算出来需要参与到动画中的值B,再将动画值B传入AnimatorUpdateListener中的onAnimationUpdate方法中操作对象进行动画(此处可以不是动画)

从何入手

上面说了,一共有三个步骤,分别调用到了三个类(接口),现在分别看看三个不同的类的用法:

Interpolator——用于控制动画效率

这里可以调用现有的几个实现类:

AccelerateDecelerateInterpolator:两头帮紧,中间孬松。就是中间快,开始和结束的时候慢

AccelerateInterpolator :开始慢,后来快

AnticipateInterpolator:先往后退一点再往前

AnticipateOvershootInterpolator:先退一点再往前再超过终点再退后

BounceInterpolator:最后弹一下

CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线

DecelerateInterpolator:先快后慢

LinearInterpolator:匀速

OvershootInterpolator:超过终点再回来

如果这些还不能满足需求,那么自己去实现一个类,它会让你重写getInterpolation方法,这里入参是一个float类型,这个float由ValueAnimator计算并传入,传入时是匀速从0增长到1的,根据这个值就可以带入计算后再返回其他的值了,需要注意的是要控制计算后的值也应该是由0最后到1的,中间可以到2,也可以是-1,但是最终结果最好是1,这样有利于之后的调用。需要用到曾经学过的很多数学知识了,什么赛赢,阔赛赢,谭建提,阔谭建提之类的,再厉害点的可以加入Log,椭圆,双曲线等等,虽然很难,但是如果你执意要做,我也只能说厉害了,我的哥。

TypeEvaluator——计算产生动画需要的值

这个东西需要自己去实现它,并重写evaluate方法,该方法入参float fraction, Object startValue, Object endValue,这里这个fraction就是上面Interpolator计算出来的值了。startValue和endValue就是起始值了,这里是Object,那代表这里的值可以是任何自定义类型,可以自己写一个Java类来进行数据包装,也可以传一个HashMap,都是可以的。然后在这个方法里面进行计算之后,再返回一个Object类型的值,也可以是返回任何值。

AnimatorUpdateListener——根据值进行动画

这里是最后一步了。上面TypeEvaluator计算好的值会被传入到这里的onAnimationUpdate方法中,但是这里并不是直接传进来的Object,而是传入的ValueAnimator对象,可以使用ValueAnimator.getAnimaterdValue()方法获取到刚才计算出来的Object对象,然后进行动画变换。也可以不是动画,反正这里都已经取到值了,这个值能够拿来做的事情就多了去了。

为何不用Handler

额,自己体会吧。

一个DEMO

ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(),startValue,endValue);
animator.addUpdateListener(new MyUpdateListener(view));
animator.setInterpolator(new AccelerateInterpolator());
animator.setDuration(2000);
animator.start();

class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {

View v;

public MyUpdateListener(View v) {
this.v = v;
}

@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
PointF point = (PointF) valueAnimator.getAnimatedValue();
LayoutParams params = (LayoutParams) v.getLayoutParams();
params.setMargins((int) point.x, (int) point.y + paddingTop, 0, 0);
v.setLayoutParams(params);
}
}

class PointEvaluator implements TypeEvaluator {

@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {

PointF start = (PointF) startValue;

PointF end = (PointF) endValue;

float y = start.y + fraction * (end.y - start.y);

return new PointF(start.x, y);
}

}


上面就是一个加速下落的动画,如果要变成弧线,可以这样写一个TypeEvaluator:

class PointEvaluator implements TypeEvaluator {

@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {

PointF start = (PointF) startValue;

PointF end = (PointF) endValue;

float x = start.x + fraction * (end.x - start.x);

float width = end.x - start.x;
if (width < 0) {
width *= -1;
}
float circleX = fraction * width;

float y = (float) ((2 * width - Math.sqrt(Math.pow((2 * (double) width), 2) - 4 * Math.pow((double) circleX, 2))) / 2);//这里取的四分之一个圆的弧线
return new PointF(y, x);
}

}


还有一个ofInt的方法,这个方法只需要传入开始的值和结束的值即可,在UpdateListener的那里getValue出来的时候强制转换成int来使用,相当于这里它里面有一个默认的TypeEvaluator了,其他都是相同的,不赘述了。

最后

在仔细阅读本文之后,试着去写一个小demo,相信你就能够明白ValueAnimator的运行原理了。当你成为一个old driver的时候再回来看这个文章,你也能够轻轻松松的自己实现一个ValueAnimator的类了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 动画
相关文章推荐