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

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

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

  1. 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,谢谢

你可能感兴趣的:(框架,动画,android,view,animation)