Android 属性动画Property Animation(下)

本篇来介绍一下属性动画中另一个重要的类ObjectAnimator~

ObjectAnimator

ObjectAnimatorValueAnimator的子类,它是可以直接对任意对象的任意属性进行动画操作的,因为ValueAnimator是父类,所以ValueAnimator中可以使用的方法在ObjectAnimator中也是可以使用的,ObjectAnimator可以用XML表示,创建object_anim.xml如下:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueTo="200"
    android:valueType="floatType"
    android:propertyName="y"
    android:repeatCount="1"
    android:repeatMode="reverse"/>

代码中调用XML文件:

ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_anim);
objectAnimator.setTarget(myObject);
objectAnimator.start();

如果想创建更复杂一些的动画,需要用到PropertyValuesHolder来对各个属性分别做动画,如:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="1000"
                android:repeatCount="1"
                android:repeatMode="reverse">
    <propertyValuesHolder android:propertyName="x" android:valueTo="400"/>
    <propertyValuesHolder android:propertyName="y" android:valueTo="200"/>
</objectAnimator>

如果想更复杂一些,还要用到keyframe (关键帧),fraction是当前进度,取值范围(0,1),插值器interpolator 是可选的,默认是 AccelerateDecelerateInterpolator,示例:

<propertyValuesHolder android:propertyName="x" >
    <keyframe android:fraction="0" android:value="800" />
    <keyframe android:fraction=".2"
              android:interpolator="@android:anim/accelerate_interpolator"
              android:value="1000" />
    <keyframe android:fraction="1"
              android:interpolator="@android:anim/accelerate_interpolator"
              android:value="400" />
</propertyValuesHolder>
<propertyValuesHolder android:propertyName="y" >
    <keyframe/>
    <keyframe android:fraction=".2"
              android:interpolator="@android:anim/accelerate_interpolator"
              android:value="300"/>
    <keyframe android:interpolator="@android:anim/accelerate_interpolator"
              android:value="1000" />
</propertyValuesHolder>

代码中使用ObjectAnimator:

//ofFloat(Object target, String propertyName, float... values) 
//第一个参数为object类型的target,这里是textview
//第二个参数是要做动画的属性值
//最后一个可以传入任意个数的参数,动画在他们数值之间过渡
 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv_text, "rotation", 0f, 20f, -20f, 20f, -20f, 0f);
 //动画时长
  objectAnimator.setDuration(3000);
  //动画重复次数
  objectAnimator.setRepeatCount(2);
  //动画重复模式
  objectAnimator.setRepeatMode(ValueAnimator.RESTART);
  //设置动画插值器
  objectAnimator.setInterpolator(new AccelerateInterpolator());
  //设置监听器
  objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                Log.e("TTT", "value is " + value);
            }
        });
  //启动动画
  objectAnimator.start();

ofFloat()中第二个参数传入属性值的是"rotation",那么这个参数都可以用哪些值呢?答案是任何值!因为ObjectAnimator针对于任意对象的,它的工作就是不断地向某个对象中的某个属性进行赋值,然后对象根据属性值的改变再来决定如何展现出来。系统不会根据这个属性值名称去查找,而是会查找对应的get和set方法。

上面代码效果图:
object_animator.gif

自定义Evaluator

上面使用的是ObjectAnimator.ofFloat()来创建浮点数值的ObjectAnimator实例,那么如果想创建自定义object的ObjectAnimator实例呢?这时就要用ObjectAnimator.ofObject()来创建了,如:

ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)

这里要用到自定义Evaluator 了,Android 属性动画Property Animation(上) 中已经介绍过,Evaluator通过给定的动画起始值(startValue)和结束值(endValue)以及动画当前进度(fraction)来计算当前动画的进度值。先来看下几个常用的Evaluator,

IntEvaluator

public class IntEvaluator implements TypeEvaluator<Integer> {
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }
}

FloatEvaluator

public class FloatEvaluator implements TypeEvaluator<Number> {
    public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
}

返回的当前进度值=起始值+(结束值-起始值) x 当前进度,ArgbEvaluator也是一样道理。如果用ofInt()来定义动画,动画中的进度值应该都是整形的,如果用ofFloat()来定义动画,那么动画中的值也都是浮点型的。以ofFloat(0.0f,1.0f)为例:起始值为0.0f,结束值是1.0f,假如当前进度(fraction)为50%,则当前进度值=0.0f+(1.0f-0.0f)x 0.5=0.5,在AnimatorUpdateListener监听器中通过animation.getAnimatedValue()函数拿到Evaluator中返回的值,如果需要自定义Evaluator,则需要实现TypeEvaluator接口:

TypeEvaluator

 public class MyEvalutor implements TypeEvaluator {
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            return null;
        }
    }

下面创建一个自定义object的ObjectAnimator例子,先定义一个ObInfo类:

 public class ObInfo implements Serializable {
     public int color;//用来定义颜色
     public float x; //用来定义X轴
     public float y; //用来定义Y轴

     public ObInfo(int color, float x, float y) {
         this.color = color;
         this.x = x;
         this.y = y;
        }
    }

接着自定义TypeEvaluator :

 public class MyEvalutor implements TypeEvaluator<ObInfo> {

   @Override
   public ObInfo evaluate(float fraction, ObInfo startValue, ObInfo endValue) {
       float x = startValue.x + fraction * (endValue.x - startValue.x);
       float y = startValue.y + fraction * (endValue.y - startValue.y);
       int color = (int) (startValue.color + fraction * (endValue.color - startValue.color));
       return new ObInfo(color, x, y);
        }
    }

最后实现动画:

ObInfo info1 = new ObInfo(0xffffff00, 500, 200);
ObInfo info2 = new ObInfo(0xff0000ff, 500, 1000);
ValueAnimator animator = ValueAnimator.ofObject(new MyEvalutor(), info1, info2, info1);
animator.setDuration(4000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        ObInfo info = (ObInfo) animation.getAnimatedValue();
        tv_text.layout(tv_text.getLeft(), (int) info.y, tv_text.getRight(), (int) (info.y + tv_text.getHeight()));
        tv_text.setTextColor(info.color);
    }
  });
animator.start();

文字先往下移动,再返回原处,移动过程中颜色也不断变化,效果图:
evalutor.gif

如果想监听动画过程只需添加监听器:

    objectAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
              //动画开始前调用
            }

            @Override
            public void onAnimationEnd(Animator animation) {
              //动画结束时调用
            }

            @Override
            public void onAnimationCancel(Animator animation) {
              //动画取消时调用
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
              //动画重复执行时调用
            }
        });

如果只想用其中的一个,只需改成适配器类AnimatorListenerAdapter即可:

 objectAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {
                super.onAnimationCancel(animation);
            }
        });
常用方法备注
ofFloat、ofInt、ofArgb、ofObject、ofPropertyValuesHolderofFloat(),ofInt(),ofArgb(),ofObject(),ofPropertyValuesHolder()分别是用来创建浮点型、整形、颜色值、自定义object、包含PropertyValuesHolder的animator实例
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小马快跑_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值