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

自定义View时,用到Paint Canvas的一些温故,PropertyAnimation中的ValueAnimator(动画四,“大大姐”的旋转跳跃no.2)

2016-01-07 16:03 681 查看

转载请注明出处王亟亟的大牛之路

这些天都在说画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。(等会就讲这个)

TypeEvaluator则是动画中需要变化的属性值的计算类。Android提供了三种:用于计算int类型属性的IntEvaluator,用于计算float类型属性的FloatEvaluator,和用于计算rgb颜色类属性的ArgbEvaluator。若上面的三种均无法满足你的需求,则你可以自定义属性计算类。

接下来贴下“栗子”代码,我们边说边理解

先贴下包结构



还是我们之前”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就是在这上面加工能做的,所以更好用。

再给我们的ValueAnimator增加了Animator.AnimatorListener()监听器,那么这个监听器的回调又是干嘛的呢?


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,谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: