和ys一起学动画——传统动画与属性动画(二)

忙了几天,又到周五了,虽然周五写bolg好像很少人看,不过无所谓啦。主要总结和自己看看。

本文承接和ys一起学动画——传统动画与属性动画(一) 一文继续介绍关于属性动画的一些知识和自己的demo。

本来打算再往demo里面新加一点内容的。。后来忙了一下,就没高兴写了。。

好了,进入正题。

属性动画

属性动画(Property Animation)是一个很强劲的动画框架,几乎可以为所有的事物加上动画效果。你可以定义一个动画去改变任何对象的属性,不管该对象是否在屏幕上,都可以进行绘制。一个属性动画在某一个时间段,改变的是一个对象的一个属性值(一个对象的一个字段)。原理就是这样。

属性动画相关的类

ObjectAnimator 对象动画执行类
ValueAnimator 值动画执行类
AnimatorSet 一组动画的执行,有多种方式(一起执行,自定义顺序执行等)
AnimtorInflater 加载xml文件类
TypeEvaluator 类型估值,主要用于设置动画操作属性的值
TimeInterpolator 时间插值器

属性动画的属性

Duration:
动画的持续时间
TimeInterpolation: 
用于定义动画变化率的接口,所有插值器都必须实现此接口,有线性,非线性插值器。
TypeEvaluator: 
用于定义属性值计算方式的接口,有int,float,color类型,根据属性的起始、结束值和插值一起计算出当前时间的属性值,可以使用PropertyValuesHolder来捆绑多个值的变化。
Animation sets: 
动画集合,即可以同时对一个对象应用多个动画,这些动画可以同时播放也可以对不同动画设置不同的延迟
Frame refreash delay: 
多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影响
Repeat Country and behavoir:
重复次数与方式,如播放3次、5次、无限循环,可以让此动画一直重复,或播放完时向反向播放

对于View的属性来说:

1)translationX 和 translationY:这两个属性控制了View所处的位置,
     它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。

2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。它的表现跟Tween Animation中的RotateAnimation不一致。
RotateAnimation 的旋转,表现为平面的旋转
而rotationX、Y 旋转,是立体的旋转,默认是以View的中心点,做rotation(x,y)过中心点的直线,面向该直线进行翻转

3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。

4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。

5)x 和 y:描述了view在其父容器中的最终位置,是左上角坐标和偏移量(translationX,translationY)的和。

6)aplha:透明度,1是完全不透明,0是完全透明。

具体使用方法

通过调用执行类的ofFloat等方法就可以完成对动画的初始化,支持的值类型有float,int,keyframe,object以及PropertyValuesHolder。当然,不要忘记调用setDuration和start喔。

1.ObjectAnimator
对象动画,顾名思义,你可以为其指定一个Target对象,然后对其的某个属性进行值的变化从而达到动画效果。使用对象动画有两个条件:
①需要变化的属性必须要有对应的set,get方法;
②指定的属性必须是UI相关的,不然看不到效果。

//方法一 直接使用,单属性
        ObjectAnimator//  
        .ofFloat(view, "rotationX", 0.0F, 360.0F)//参数:变化的View,变化的属性,变化的值(为可变长参数)
        .setDuration(500)//  变化的总时长
        .start();  // 启动动画

欸对了,听说换成妹子图才有人气,我得马上试试。
妹子效果图

//方法二,为动画设置监听器,重写onAnimationUpdate自己实现多个属性的修改(可对相同的值进行不同处理)
        ObjectAnimator anim = ObjectAnimator//  
                .ofFloat(view, "zhy", 1.0F,  1.5F)//  
                .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);  
            }  
        });  

这里写图片描述

//方法三,使用PropertyValuesHolder 捆绑多个需要改变的属性字段(可设置不同的值)
        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();  

这里写图片描述

2.ValueAnimator
值动画仅仅接受值作为参数,不需要之前的属性名,自然也没有了必须用对象得有set、get方法的限制。但是往往需要我们自己去实现它的update逻辑。

这里我实现了一个自由落体效果

    /** 
     * 自由落体
     * @param view 
     */  
    public void verticalRun( View view)  
    {  
        ValueAnimator animator = ValueAnimator.ofFloat(0.0f,1f);  
        animator.setTarget(mBlueBall1);  
        animator.setDuration(1000).start();
        animator.setInterpolator(new LinearInterpolator());  
        animator.addListener(new AnimatorListener() {

            @Override
            public void onAnimationStart(Animator animation) {
                // TODO Auto-generated method stub
                Log.i(TAG,"drop start");
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                // TODO Auto-generated method stub
                Log.i(TAG,"drop repeat");
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                // TODO Auto-generated method stub
                Log.i(TAG,"drop end");
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                // TODO Auto-generated method stub
                Log.i(TAG,"drop cancel");
            }
        });

        animator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                //自己实现逻辑
                float temp = (Float) animation.getAnimatedValue();
                mBlueBall1.setTranslationY((float)(mScreenHeight - mBlueBall.getHeight()) * temp * temp); 
            }  
        });

    }

这里写图片描述

还有一个抛物线效果

    /** 
     * 抛物线
     * @param view 
     */  
    public void paowuxian(View view)  
    {  

        ValueAnimator valueAnimator = new ValueAnimator();  
        valueAnimator.setDuration(1000);  
        valueAnimator.setObjectValues(new PointF(0, 0),new PointF(mScreenWidth - mBlueBall.getWidth(),mScreenHeight - mBlueBall1.getHeight()));  
        valueAnimator.setInterpolator(new LinearInterpolator());  
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>()  
        {  
            // fraction = t / duration  
            @Override  
            public PointF evaluate(float fraction, PointF startValue,  
                    PointF endValue)  
            {  
                float maxa = (float) (endValue.x - startValue.x);
                float maxb = (float) (endValue.y - startValue.y);
                PointF point = new PointF();  
                point.x = maxa * fraction;  
                point.y = maxb * (fraction * fraction); 
                return point;  
            }  
        });  

        valueAnimator.start();  
        valueAnimator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                PointF point = (PointF) animation.getAnimatedValue();  
                mBlueBall.setTranslationX(point.x);  
                mBlueBall.setTranslationY(point.y);  
            }  
        });  
    }  

这里写图片描述

两球同时落地(需要都使用线性时间插值器,才能达到这样的效果):
这里写图片描述

3.AnimatorSet
一组动画的执行,有多种方式(一起执行,自定义顺序执行等)

简单易懂的代码:

    private void onebyone() {
        // TODO Auto-generated method stub
        float cx = mBlueBall.getX();  

        ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",  
                1.0f, 2f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",  
                1.0f, 2f);  
        ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall,  
                "x",  cx , 0f);  
        ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall,  
                "x", cx);  
        /** 
         * anim1,anim2,anim3,anim4依次执行
         */  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim1).before(anim2);  
        animSet.play(anim2).before(anim3);  
        animSet.play(anim4).after(anim3);  
        animSet.setDuration(2000);  
        animSet.start();  
    }

    private void together() {
        // TODO Auto-generated method stub
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",  
                0.5f, 2f ,0.5f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",  
                0.5f, 2f ,0.5f);  
        ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall, "alpha",  
                1.0f, 0.0f ,1.0f);  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.setDuration(2000);  
        animSet.setInterpolator(new LinearInterpolator());  
        //一起执行
        animSet.playTogether(anim1, anim2,anim3);  
        animSet.start();  
    }

(稍后会补充一些关于LayoutAnimator的内容,插值器前面已经讲了这边我就不再赘述了)

小结

其实属性动画用起来没有那么困难,做出来效果也蛮不错的,这里放出demo给大家下载。以后的demo都免费提供吧 。

Demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值