Android动画之Animator

Animator动画可以用xml文件描述和java程序实现。先上一张Animator的官方结构图

xml实现,新建描述文件res/animator/animator_set1.xml,注意文件放在animator目录下面。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <objectAnimator
        android:duration="2000"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="alpha"
        android:repeatCount="1"
        android:repeatMode="restart"
        android:valueFrom="0"
        android:valueTo="1"
        android:valueType="floatType" />

    <objectAnimator
        android:duration="3000"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="scaleX"
        android:valueFrom="0.5"
        android:valueTo="1"
        android:valueType="floatType" />
</set>

属性解释:
ordering:有两个值sequentially和together,前者表示顺序播放后者是同时播

duration:动画播放时长
interpolator:值插器,简单来说就是控制动画播放速率的(可以自行查找下)
propertyName:此动画要作用的View的属性名称,一般有getter和setter方法的的属性都可以使用
repeatCount:动画重复次数,注意第一次播放不算是重复,所以如果想动画播放两次,值为1就行
repeatMode:重复的模式,两个值restart和reverse,reverse是指按原动画倒着来一次,restart自然就是重新播一遍动画
valueFrom:propertyName属性的起始值,valueTo就是结束值,valueType属性值的数值类型

程序中使用:

AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_set1);
        animatorSet.setTarget(imageView);
        animatorSet.start();

用java当然也可以达到上面效果,AnimatorSet提供了几个方法playSequentially()、playTogether()都可以接收ObjecAnimator的Array或者List实现Animator的顺序或者同时播放

ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);
        animatorA.setDuration(2000);
        ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f);
        animatorB.setDuration(3000);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(animatorA, animatorB);
        animatorSet.start();
或者
ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);
        animatorA.setDuration(2000);
        ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f);
        animatorB.setDuration(3000);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(animatorA).before(animatorB);
        animatorSet.start();
这样animatorA播完以后播animatorB,这时候如果有需要和animatorA同时播放的的animatorC,则可以这样animatorSet.play(animatorA).with(animatorA).before(animatorB),with表示和他前面离with最近的动作一起执行,此时就是animatorA。其实看源码就知道playTogether的内部是实现就是依靠多次with调用来做的。

另一种稍微复杂一点的描述:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <objectAnimator
        android:duration="2000"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="alpha"
        android:valueFrom="0"
        android:valueTo="1"
        android:valueType="floatType" />

    <objectAnimator
        android:duration="5000"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator">

        <propertyValuesHolder
            android:propertyName="scaleX"
            android:valueFrom="0.5"
            android:valueTo="1.0"
            android:valueType="floatType" />
        <propertyValuesHolder android:propertyName="x">
            <keyframe
                android:fraction="0.3"
                android:value="600" />
            <keyframe
                android:fraction="1"
                android:value="350" />
        </propertyValuesHolder>
        <propertyValuesHolder android:propertyName="y">
            <keyframe
                android:fraction="0.3"
                android:value="200" />
            <keyframe
                android:fraction="1"
                android:value="300" />
        </propertyValuesHolder>
    </objectAnimator>


</set>


用keyframe完成一个运行轨迹,使用这种方法的时候keyframe的上层标签objectAnimator不要再描述某些属性,如android:propertyName="scaleX",不然keyframe将失效。
keyframe的其他属性没什么特别,说下fraction属性,其取值0<= fraction <=1,动画时间是fraction的作用对象,0表示起始时间1表示结束时间,中间小数是动画时间的百分比。运行过程中也可以用interpolator设置速率。同上简单的java引入就可以使用

用java实现:

ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);
        animatorA.setDuration(2000);

        PropertyValuesHolder propertyValuesHolder0 = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1.0f);
        Keyframe keyframe1 = Keyframe.ofFloat(0.3f, 600);
        Keyframe keyframe2 = Keyframe.ofFloat(1f, 350);
        PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofKeyframe("x", keyframe1, keyframe2);
        Keyframe keyframe3 = Keyframe.ofFloat(0.3f, 200);
        Keyframe keyframe4 = Keyframe.ofFloat(1f, 300);
        PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofKeyframe("y", keyframe3, keyframe4);
        ObjectAnimator animatorB = ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder0, propertyValuesHolder1, propertyValuesHolder2);
        animatorB.setDuration(5000);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(animatorA).before(animatorB);
        animatorSet.start();
ObjectAnimator和ProperyValuesHolder都有ofFloat和ofInt不同的是ObjectAnimator比PropertyValuesHolder都多了一个作用对象也就是参数中的target。注意PropertyValuesHolder中只有一个Keyframe会出错的至少有两个才行。从以上这些例子中不难发现ObjectAnimator中的PropertyValuesHolder都是同时执行的动画。

使用ofObject做动画的时候要指明Evaluator,否则系统不知道这个Object是什么该怎么去计算,如PropertryValuesHolder的ofObject函数也能获得PropertryValuesHolder的实例,使用的时候要指明Evaluator。

        TypeEvaluator<Float> evaluator = new TypeEvaluator<Float>() {
            float startInt;
            @Override
            public Float evaluate(float fraction, Float startValue, Float endValue) {
                startInt  = startValue;
		// fraction是当前运动时间占总动画时间的比值
                return startInt + fraction * (endValue - startValue);
            }
        };

        ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);
        animatorA.setDuration(2000);
        ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f);
        animatorB.setDuration(3000);
        PropertyValuesHolder propertyValuesHolder0 = PropertyValuesHolder.ofObject("y", evaluator, imgY, 300f);
        ValueAnimator valueAnimator0 = ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder0);
        valueAnimator0.setDuration(3000);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(animatorA).with(animatorB).before(valueAnimator0);
        animatorSet.start();

代码中关于ValueAnimator的部分也可以用以下代替达到上面同样的效果:

        ValueAnimator valueAnimator0 = new ValueAnimator();
        valueAnimator0.setTarget(imageView);
        valueAnimator0.setObjectValues(imgY, 300f);
        valueAnimator0.setEvaluator(evaluator);
        valueAnimator0.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float y = (float) animation.getAnimatedValue();
                imageView.setY(y);
            }
        });

AnimatorUpdateListener是对动画的值更新进行监听,我们能在回调函数中获取到某属性当前的值,单一属性值的改变不用指定属性名称如上。

还有一个简单的动画类,ViewPropertyAnimator,使用很简单,简单的动画可以用它
        ViewPropertyAnimator propertyAnimator = imageView.animate();
        propertyAnimator.translationXBy(100)
                .setDuration(1000)
                .start();


Animator的监听器添加addListener():

new AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}
            @Override
            public void onAnimationRepeat(Animator animation) {}
            @Override
            public void onAnimationEnd(Animator animation) {}
            @Override
            public void onAnimationCancel(Animator animation) {}
        }
// 对AnimatorListener的空实现,并且多出两个    
 new AnimatorListenerAdapter() {

            @Override
            public void onAnimationCancel(Animator animation) {}
            @Override
            public void onAnimationEnd(Animator animation) {}
            @Override
            public void onAnimationRepeat(Animator animation) {}
            @Override
            public void onAnimationStart(Animator animation) {}
            @Override
            public void onAnimationPause(Animator animation) {}
            @Override
            public void onAnimationResume(Animator animation) {}

        }


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值