android属性动画完全解析

1.ObjectAnimator属性动画

1.1、第一个参数为view对象,第二个参数为要改变的属性,第三个参数为起始值,第四个参数为结束值。(注:如果只有三个参数,则第三个参数为结束值,起始值为view当前的值,第二个参数为view的属性,且该属性必须要有get和set的方法,即getPropName和setPropName)
animator.addListener,addPauseListener,addUpdateListener可以去监听动画的开始,结束,重复,暂停,继续,更新等。AnimatorListenerAdapter简化了事件需要监听的事件,做了空实现,只需要关注你关注的动画事件即可

 ObjectAnimator//  在500毫秒内旋转360.ofFloat(view, "rotationX", 0.0F, 360.0F)//  
         .setDuration(500)//  
         .start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ObjectAnimator//在2秒内由红色渐变成绿色
     .ofArgb(list.get(0),"backgroundColor",0xffff0000,0xff00ff00).setDuration(2000).start();
        }

1.2、如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。

anim.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
              view.postInvalidate(); //用于在子线程更新ui 
              view.invalidate();  //用于在ui现场更新ui
            }  
        });

1.3、上面的操作属性只有一个,那么如果我希望一个动画能够让View既可以缩小、又能够淡出(3个属性scaleX,scaleY,alpha)

public void rotateyAnimRun(final View view)  
{  //第二个参数是我们随便写的(不存在的),我们主要是在这个动画里面的值的变化速率,然后在动画监听里面去手动去修改你想要变的值
    ObjectAnimator anim = ObjectAnimator//  
            .ofFloat(view, "zhy", 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);  
        }  
    });  
}

2ValueAnimator属性动画

2.1、这样的好处是不需要操作的对象的属性一定要有get和set方法

 ValueAnimator animator = ValueAnimator.ofFloat(0, height);  
        animator.setTarget(view);  
        animator.setDuration(1000).start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
//处理你想要的view的动画
view.setTranslationY((Float) animation.getAnimatedValue());
                }
            });

3 AnimatorSet的使用

float cx = view.getX();  

        ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "scaleX",  
                1.0f, 2f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, "scaleY",  
                1.0f, 2f);  
        ObjectAnimator anim3 = ObjectAnimator.ofFloat(view,  
                "x",  cx ,  0f);  
        ObjectAnimator anim4 = ObjectAnimator.ofFloat(view,  
                "x", cx);  

        /** 
         * anim1,anim2,anim3同时执行 
         * anim4接着执行 
         * play,with,before,after的参数都是动画,after的参数还可以是时间
         */  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim1).with(anim2);  
        animSet.play(anim2).with(anim3);  
        animSet.play(anim4).after(anim3); 
        /** 
         * anim1,anim2同时执行 
         */
         animSet.playTogether(anim1, anim2);
        animSet.setDuration(1000);  
        animSet.start(); 

4 插值器

AccelerateDecelerateInterpolator============动画开始与结束的地方速率改变比较慢,在中间的时候加速。
这里写图片描述
AccelerateInterpolator===================动画开始的地方速率改变比较慢,然后开始加速。
这里写图片描述
AnticipateInterpolator ==================开始的时候向后然后向前甩。
这里写图片描述
AnticipateOvershootInterpolator=============开始的时候向后然后向前甩一定值后返回最后的值。
这里写图片描述
BounceInterpolator=====================动画结束的时候弹起。
这里写图片描述
CycleInterpolator======================动画循环播放特定的次数,速率改变沿着正弦曲线。
这里写图片描述
DecelerateInterpolator===================在动画开始的地方快然后慢。
这里写图片描述
这里写图片描述创建的时候,可以传factor值,如DecelerateInterpolator(2f):
LinearInterpolator======================以常量速率改变。
OvershootInterpolator====================向前甩一定值后再回到原来位置。
这里写图片描述
这里写图片描述创建的时候,可以传tension值,OvershootInterpolator(0.8f):
PathInterpolator========================新增的,就是可以定义路径坐标,然后可以按照路径坐标来跑动;注意其坐标并不是 XY,而是单方向,也就是我可以从0~1,然后弹回0.5 然后又弹到0.7 有到0.3,直到最后时间结束。

5使用xml文件来创建属性动画

5.1、单个动画

//动画的xml文件,名字scalex.xml,位置res/animator/scalex.xml
<?xml version="1.0" encoding="utf-8"?>  
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
    android:duration="1000"  
    android:propertyName="scaleX"  
    android:valueFrom="1.0"  
    android:valueTo="2.0"  
    android:valueType="floatType" >  
</objectAnimator>  

public void scaleX(View view)  
    {  
        // 加载动画  
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);  
        anim.setTarget(mMv);  
        anim.start();  
    }

5.2 动画集合

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:ordering="together" >  
  //使用set标签,有一个orderring属性设置为together同时执行,sequentially表示一个接一个执行
    <objectAnimator  
        android:duration="1000"  
        android:propertyName="scaleX"  
        android:valueFrom="1"  
        android:valueTo="0.5" >  
    </objectAnimator>  
    <objectAnimator  
        android:duration="1000"  
        android:propertyName="scaleY"  
        android:valueFrom="1"  
        android:valueTo="0.5" >  
    </objectAnimator>  

</set> 

//缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);  
//纵向缩小以左上角为中心点
        mMv.setPivotX(0);  
        mMv.setPivotY(0);  
        //显示的调用invalidate  
        mMv.invalidate();  
        anim.setTarget(mMv);  
        anim.start();

6View的anim方法

view.animate()//  
                .alpha(0)//  
                .y(mScreenHeight).setDuration(1000)  
                // need API 12  
                .withStartAction(new Runnable()  
                {  
                    @Override  
                    public void run()  
                    {  
                        Log.e(TAG, "START");  
                    }  
                    // need API 16  
                }).withEndAction(new Runnable()  
                {  

                   @Override  
                    public void run()  
                    {  
                        Log.e(TAG, "END");  
                        runOnUiThread(new Runnable()  
                        {  
                            @Override  
                            public void run()  
                            {  
                                mBlueBall.setY(0);  
                                mBlueBall.setAlpha(1.0f);  
                            }  
                        });  
                    }  
                }).start(); 

7PropertyValuesHolder 有时候可以代替AnimatorSet

  Keyframe keyframe1 = Keyframe.ofFloat(0.0f,0);
        Keyframe keyframe2 = Keyframe.ofFloat(0.25f,-30);
        Keyframe keyframe3 = Keyframe.ofFloat(0.5f,0);
        Keyframe keyframe4 = Keyframe.ofFloat(0.75f, 30);
        Keyframe keyframe5 = Keyframe.ofFloat(1.0f,0);
        PropertyValuesHolder rotation = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3, keyframe4,keyframe5);

        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha",1.0f,0.2f,1.0f);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.2f,1.0f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.2f,1.0f);
        PropertyValuesHolder color = PropertyValuesHolder.ofInt("BackgroundColor", 0XFFFFFF00, 0XFF0000FF);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mButton, alpha, scaleX, scaleY,color,rotation);
        animator.setInterpolator(new OvershootInterpolator());
        animator.setDuration(5000).start();

8动画变化速率不一致的办法

ValueAnimator valueAnimator = new ValueAnimator();  
        valueAnimator.setDuration(3000);  
        valueAnimator.setObjectValues(new PointF(0, 0));  
        valueAnimator.setInterpolator(new LinearInterpolator());  
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>()  
        {  
            // fraction = t / duration  
            @Override  
            public PointF evaluate(float fraction, PointF startValue,  
                    PointF endValue)  
            {  
                Log.e(TAG, fraction * 3 + "");  
                // x方向200px/s ,则y方向0.5 * 10 * t  
                PointF point = new PointF();  
                point.x = 200 * fraction * 3;  
                point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);  
                return point;  
            }  
        });  

        valueAnimator.start();  
        valueAnimator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                PointF point = (PointF) animation.getAnimatedValue();  
                view.setX(point.x);  
                view.setY(point.y);  

            }  
        }); 

大部分内容引用于lmj623565791
插值器内容引用于linghu_javalgaojiantong

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值