这些天都在说画view,view的一些动画,不知不觉已经2个礼拜了,这篇是讲的之前漏说的ValueAnimator。
先补一下之间没有贴的Property Animation的框架
Animator
--ValueAnimator --ObjectAnimator --AnimatorSet AnimatorInflater
Keyframe
KeyframeSet
PropertyValuesHolder
AnimatorListenerAdapter.java TypeEvaluator
--IntEvaluator --FloatEvaluator --ArgbEvaluator
其中ObjectAnimator,AnimatorSet,PropertyValuesHolder在我们之前的文章已经说过了,AnimatorInflater有简略的带过(网上有很多例子可以搜下),没有看过的小伙伴们可以看下传送门http://blog.csdn.net/ddwhan0123/article/details/50470237
先解释下,上面的架构图,让大家能对整体类与类的关系更清晰了解。
1.Animator, ValueAnimator, ObjectAnimator是描述动画的核心类。其中,Animator是父类,它定义了动画开始/结束/暂停/恢复/重复等接口,并实现了公共函数。ValueAnimator和ObjectAnimator是描述动画的具体类
2.Keyframe是关键帧,通过关键帧可以实现较复杂的动画(例如,曲线运动等)。KeyframeSet是关键帧的辅助类。
3.AnimatorUpdateListener中实现了全部的动画监听接口。但是,监听函数体都没有执行任何动作。在我们需要监听动画相应动作时,可以实现Animator提供的接口,也可以继承于AnimatorUpdateListener。(等会就讲这个)
接下来贴下“栗子”代码,我们边说边理解
先贴下包结构
还是我们之前”TF”男孩的那个包,今天的代码还是用java代码实现的并没有使用xml。
贴一下主要实现的两个方法
private void makeValueAnimatorTranslationX() {
//创建ValueAnimator对象,并初始化
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 200, 0);
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
LogUtils.d("--->onAnimationStart");
}
@Override
public void onAnimationEnd(Animator animation) {
LogUtils.d("--->onAnimationEnd");
}
@Override
public void onAnimationCancel(Animator animation) {
LogUtils.d("--->onAnimationCancel");
}
@Override
public void onAnimationRepeat(Animator animation) {
LogUtils.d("--->onAnimationRepeat");
}
});
//属性变化大监听器
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animationorValue = (Integer) animation.getAnimatedValue();
LogUtils.d("--->当前进度值: " + animationorValue);
imageView.setTranslationX(animationorValue);
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(4);
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
//绑定需要执行动画的对象
valueAnimator.setTarget(imageView);
valueAnimator.start();
}
private void makeValueAnimatorScale() {
PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 2.0f, 1.0f);
PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 2.0f, 1.0f);
ValueAnimator valueAnimator=ValueAnimator.ofPropertyValuesHolder(propertyValuesHolder1,propertyValuesHolder2);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float xValue=(float)animation.getAnimatedValue("scaleX");
float YValue=(float)animation.getAnimatedValue("scaleY");
imageView.setScaleX(xValue);
imageView.setScaleY(YValue);
}
});
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(2);
valueAnimator.setRepeatMode(Animation.RESTART);
valueAnimator.setTarget(imageView);
valueAnimator.start();
}
我们这两个方法,一个是平移效果,一个是放大效果。
这2种实现其实我们前两篇都已经大篇幅相惜的写了代码,那这一部分又有什么区别呢?理由在下面。。。。(掩面而泣)
当然,也是因为这个实现比较麻烦,我第一时间并没有想用这个做平移等效果,ok废话不说,来解释代码
首先我们声明了一个ValueAnimator对象,并且对他进行了赋值,(0, 200, 0),乍看之下和之前的ObjectAnimator差不多。对,没错,ObjectAnimator就是在这上面加工能做的,所以更好用。
Animator.AnimatorListener:
onAnimationStart() —— 动画开始时调用;
onAnimationEnd() —— 动画结束时调用;
onAnimationRepeat() —— 动画循环播放时调用;
onAnimationCancel() —— 动画被取消时调用。不管终止的方式如何,被取消的动画仍然会调onAnimationEnd();
我们可以再动画运行的各个阶段加入我们的业务逻辑。
然后我们给我们的ValueAnimator添加了ValueAnimator.AnimatorUpdateListener()监听器,它可以让我们使用animation.getAnimatedValue()来获取动画之行的进展。
然后我们在他的回调函数中设置了我们的业务逻辑,让大大姐沿着x轴平移 imageView.setTranslationX(animationorValue);
再之后就喝之前一样设置时间啊,重复次数什么的
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(4);
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
记得还要把大大姐跟这个动画绑一下
//绑定需要执行动画的对象
valueAnimator.setTarget(imageView);
最后start()一下就好了 valueAnimator.start();
那我们再来简单解释下第二个例子,多动画“组合拳”
xy向同时放大
大致代码是差不多的,有2处不尽相同
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
这里我终于加入了庐山真面目的插值器(根据自己需求吧,也可以自定义)
下面贴个自定义的栗子:
public class CustomInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
input *= 0.8f;
return input * input;
}
}
声明一个类继承TimeInterpolator,再getInterpolation回调中实现自己的业务逻辑即可。
调用类也是valueAnimator.setInterpolator(new CustomInterpolator());
就好了,非常的简便。
Keyframe部分就不做过多解释了,贴几个参考资料,大家可以更好的理解
http://developer.android.com/guide/topics/graphics/prop-animation.html
http://zhouyunan2010.iteye.com/blog/1972789
源码地址:https://github.com/ddwhan0123/BlogSample/blob/master/ViewAnimDemo.zip
感谢点个star,谢谢