Android自定义view和动画

Android动画分析(属性动画)

2017-01-18  本文已影响18人  ReturnYHH

前面我们分析了Android动画中的view动画和帧动画,这篇来说说Android中的属性动画,也是Android最后的一个动画效果


属性动画

属性动画是Api11新加入的特性,和view动画不同,它是对对象进行扩展,属性动画可以对任何对象做动画效果,甚至还可以没有对象,并且动画效果得到很大的加强,不仅仅像view动画那样只能支持4种变换,属性动画种有ValueAnimator,ObjectAnimator和AnimatorSet等概念,通过他们可以实现很棒的效果,我们可以简单的把它理解为,只要对象有这个属性,它都能实现动画效果,我们先来看看一个简单的小例子:

ObjectAnimator

  ObjectAnimator
                .ofFloat(myView, "rotationX", 0.0F, 360.0F)
                .setDuration(500)//
                .start();

这段代码的意思是说,指定view的x坐标在500ms内旋转360度,我们看看ofFloat的源码:

    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
        anim.setFloatValues(values);
        return anim;

可以看到有三个参数,第一个就是我们需要传入的对象,第二个是属性名字,第三个就是多值,我们可以看到它内部就是用ObjectAnimator 来实现的,这里注意一下,第二个属性名字如果随便写一个,轻者动画没效果,重者则崩溃,为什么呢?下篇文章会来介绍,但是如果我们需要动画有效果,那我们则需要手动调用,当我们需要一个view需要做多种动画效果的时候,我们就需要这样手动去调用,例子:

public void rotateyAnimRun(final View view)  
{  
    ObjectAnimator anim = ObjectAnimator
            .ofFloat(view, "test", 1.0F,  0.0F)  
            .setDuration(500);  
    anim.start();  
    anim.addUpdateListener(new AnimatorUpdateListener()  
    {  
        @Override  
        public void onAnimationUpdate(ValueAnimator animation)  
        {  
            float cVal = (Float) animation.getAnimatedValue();  
            view.setAlpha(cVal);  
            view.setScaleX(cVal);  
            view.setScaleY(cVal);  
        }  
    });  
}  

也可以这样写,通过一个属性的holder分别设置view要做的动画效果,然后再添加到ObjectAnimator来实现,这样更简单易懂:

public void propertyValuesHolder(View view)  
    {  
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,  
                0f, 1f);  
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,  
                0, 1f);  
        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,  
                0, 1f);  
        ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();  
    }  

ValueAnimator

ValueAnimator跟ObjectAnimator差不多,来看看一个小例子:

 ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight  
                - myView.getHeight());  
        animator.setTarget(myView);  
        animator.setDuration(1000).start();  
        animator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                mBlueBall.setTranslationY((Float) animation.getAnimatedValue());  
            }  
        });  

我们发现,它跟ObjectAnimator的差别是在于它没有设定属性名称这个参数,这样的好处在于我们可以让多个属性做这个动画效果,而不是指定某一个属性去做,灵活性更高,上面代码的意思是让我们的view在1000ms内做自由落体运动,一开始我们让view处于一个静止状态,然后不断的用屏幕的高度减去view的高度,在y坐标上做平移效果,随着高度的减少,view就自由落下

AnimatorSet

最后来说说动画集合:

  AnimatorSet animatorSet =new AnimatorSet();
        //同时执行
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(myView,"rotationX",0,360),
                ObjectAnimator.ofFloat(myView,"rotationY",0,180),
                ObjectAnimator.ofFloat(myView,"translationX",0,90),
                ObjectAnimator.ofFloat(myView,"translationY",0,90),
                ObjectAnimator.ofFloat(myView,"scaleX",1,1.5f),
                ObjectAnimator.ofFloat(myView,"scaleY",1,0.5f)
                );
        animatorSet.setDuration(1000).start();

很简单,就是将各种动画放到AnimatorSet 中,然后让他们同时执行,就可以了,假如说我们需要让动画2跟在动画1后面,动画3跟着动画2后面,依次执行,那么,我们可以这样写:

 AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim2).after(anim1);  
        animSet.play(anim3).after(anim2);  
        animSet.setDuration(1000);  
        animSet.start();  

如果我们需要让动画1,动画2同时执行,动画3跟在动画2(或者动画1)后面,我们可以这样写:

 AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim1).with(anim2);  
        animSet.play(anim3).after(anim2);  
        animSet.setDuration(1000);  
        animSet.start();  

好了,关于属性动画就到这了

上一篇下一篇

猜你喜欢

热点阅读