Android 属性动画(Property Animation) ValueAnimator 的介绍

先说下属性动画与视图动画的区别:

视图动画系统仅提供为 View 对象添加动画效果的功能,因此,如果您想为非 对象添加动画效果,则必须实现自己的代码才能做到。视图动画系统也存在一些限制,因为它仅公开 对象的部分方面来供您添加动画效果;例如,您可以对视图的缩放和旋转添加动画效果,但无法对背景颜色这样做。

视图动画系统的另一个缺点是它只会在绘制视图的位置进行修改,而不会修改实际的视图本身。例如,如果您为某个按钮添加了动画效果,使其可以在屏幕上移动,该按钮会正确绘制,但能够点击按钮的实际位置并不会更改,因此您必须通过实现自己的逻辑来处理此事件。

为了更好的里面这句话我也写了一个demo 就是动画移动前点击图片有Toast 提示,图片移动之后点击图片没有Toast 提示,点击移动之后的空白界面却有Toast 提示,也就是view动画给图片设置点击事件移动之后点击事件不起作用了,如下图效果

录制的问题鼠标没有录制出来下面gif 后面图片不显示是点击了移动之后的图片,后面又显示了是点击上面的空白

有了属性动画系统,您就可以完

全摆脱这些束缚,还可以为任何对象(视图和非视图)的任何属性添加动画效果,并且实际修改的是对象本身。属性动画系统在执行动画方面也更为强健。概括地讲,您可以为要添加动画效果的属性(例如颜色、位置或大小)分配 Animator,还可以定义动画的各个方面,例如多个 Animator 的插值和同步。

不过,视图动画系统的设置需要的时间较短,需要编写的代码也较少。如果视图动画可以完成您需要执行的所有操作,或者现有代码已按照您需要的方式运行,则无需使用属性动画系统。在某些用例中,也可以针对不同的情况同时使用这两种动画系统。

属性动画的工作原理就不说了,详情的大家可以看官网 Android Developers 地址

动画的API 地址如果有忘记的属性可以点击查看

ValueAnimator 的介绍:

The main timing engine for property animation that also computes the values for the property to be animated. It has all of the core functionality that calculates animation values and contains the timing details of each animation, information about whether an animation repeats, listeners that receive update events, and the ability to set custom types to evaluate. There are two pieces to animating properties: calculating the animated values and setting those values on the object and property that is being animated. ValueAnimator does not carry out the second piece, so you must listen for updates to values calculated by the ValueAnimator and modify the objects that you want to animate with your own logic. See the section about Animating with ValueAnimator for more information.

大致是说:

动画效果分为两个步骤:1 计算添加动画效果之后的值,以及对要添加动画效果的对象和属性设置这些值 2 自己的逻辑修改要添加动画效果的对象实现动画,

大致就是 动画的值改变了之后需要自己手动赋值对象的属性来实现动画

ValueAnimator  里面有3个方法ofInt() ,ofFloat(),ofObject(),

下面说下这2个方法的使用

1 ofInt 实现的动画如下图

 1 java 代码实现方法:

  // 设置属性数值的初始值和结束值
                ValueAnimator valueAnimator = ValueAnimator.ofInt(0,
                        400, 500, 600, 900, 600, 500, 400, 0);
                // 动画时间这里是毫秒
                valueAnimator.setDuration(3000);
                // 延迟0.5 毫秒
                valueAnimator.setStartDelay(500);
                // 设置动画次数-1 为重复播放其他次数为n+1次 例如0是1次 1是2次一次类推
                valueAnimator.setRepeatCount(-1);
                // 动画的下次执行开始位置,RESTART表示动画每次从原始的状态执行,
                // REVERSE表示动画第二次执行要从第一次改变后的状态逆向执行
                valueAnimator.setRepeatMode(ValueAnimator.RESTART);
                // 设置数值变化监听器,
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        // 获取当前变化的值
                        int currentValue = (Integer) valueAnimator.getAnimatedValue();
                        imageView.setTranslationY(currentValue);
                    }
                });
                // 开始动画
                valueAnimator.start();

2 xml 代码实现方法:

  // 加载xml文件
                ValueAnimator animator =
                        (ValueAnimator) AnimatorInflater.loadAnimator(MainActivity.this,
                                R.animator.value_int_animator);
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        // 获取当前变化的值
                        int currentValue = (Integer) animation.getAnimatedValue();
                        imageView.setTranslationX(currentValue);
                    }
                });
                // 开始
                animator.start();

创建 1个animator的文件夹 然后value_int_animator.xml 的文件 里面的内容如下

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
        android:valueFrom="0"
        android:valueTo="300"
        android:valueType="intType"
        android:duration="3000"
        android:repeatCount="10"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:repeatMode="restart">

</animator>

2 ofObject 动画实现的效果如下

1 java 代码实现

 ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f,
                        500f, 800f, 500f, 1.0f);
                // 动画时间这里是毫秒
                valueAnimator.setDuration(3000);
                // 延迟0.5 毫秒
                valueAnimator.setStartDelay(500);
                // 设置动画次数-1 为重复播放其他次数为n+1次 例如0是1次 1是2次一次类推
                valueAnimator.setRepeatCount(-1);
                // 动画的下次执行开始位置,RESTART表示动画每次从原始的状态执行,
                // REVERSE表示动画第二次执行要从第一次改变后的状态逆向执行
                valueAnimator.setRepeatMode(ValueAnimator.RESTART);
                // 设置数值变化监听器,
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        // 获取当前变化的值
                        Float currentValue = (Float) valueAnimator.getAnimatedValue();
                        int curValue = currentValue.intValue();
                        imageView.setTranslationY(curValue);
                    }
                });
                // 开始动画
                valueAnimator.start();

2 xml 方法实现

  // 加载xml文件
                ValueAnimator animator =
                        (ValueAnimator) AnimatorInflater.loadAnimator(MainActivity.this,
                                R.animator.value_float_animator);
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        // 获取当前变化的值
                        Float currentValue = (Float) animation.getAnimatedValue();
                        int curValue = currentValue.intValue();
                        imageView.setTranslationX(curValue);
                    }
                });
                // 开始
                animator.start();

创建 1个animator的文件夹 然后value_float_animator.xml 的文件 里面的内容如下

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="3000"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:repeatCount="-1"
        android:repeatMode="restart"
        android:valueFrom="0"
        android:valueTo="300"
        android:valueType="floatType">

</animator>

3 ofObject

在说这个之前先说下:ValueAnimator包含 TimeInterpolator 和 TypeEvaluator;前者用于定义动画插值,后者用于定义如何计算正在添加动画效果的属性的值

这里就先不多说了,后期会详细的介绍,先知道他们的作用即可

实现的动画如下

代码试下如下

 ValueAnimator valueAnimator = ValueAnimator.ofObject(new TypeEvaluator() {
                    @Override
                    public Object evaluate(float fraction, Object startValue, Object endValue) {
                        PointF point = new PointF();
                        point.x = fraction * 500;
                        point.y = 55 * (fraction * 3) * (fraction * 3) * fraction;
                        return point;
                    }
                }, new PointF(0, 0));
                // 动画时间这里是毫秒
                valueAnimator.setDuration(3000);
                // 延迟0.5 毫秒
                valueAnimator.setStartDelay(500);
                // 设置动画次数-1 为重复播放其他次数为n+1次 例如0是1次 1是2次一次类推
                valueAnimator.setRepeatCount(-1);
                // 动画的下次执行开始位置,RESTART表示动画每次从原始的状态执行,
                // REVERSE表示动画第二次执行要从第一次改变后的状态逆向执行
                valueAnimator.setRepeatMode(ValueAnimator.RESTART);
                // 设置数值变化监听器,
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        PointF pointF = (PointF) valueAnimator.getAnimatedValue();
                        imageView.setX(pointF.x);
                        imageView.setY(pointF.y);

                    }
                });
                // 开始动画
                valueAnimator.start();

这里先简单的说下估值器  TypeEvaluator 如果自定义的需要实现  TypeEvaluator 然后在evaluate 里面写要实现的内容

上面基本就说完了ValueAnimator 动画了,代码都有详细的注意 

最后看到方法里面有一个 ofArgb,改变颜色值的方法,自己也写了一个demo 感觉使用ofInt 也是可以的

ofArgb 实现的动画

实现的代码如下:

  ValueAnimator valueAnimator = ValueAnimator.ofArgb(0xFF5C96FF, 0xFFFBC02D,
                        0xFF4FFB2D, 0xFFC2185B, 0xFF00796B);
                // 动画时间这里是毫秒
                valueAnimator.setDuration(3000);
                // 延迟0.5 毫秒
                valueAnimator.setStartDelay(500);
                // 设置动画次数-1 为重复播放其他次数为n+1次 例如0是1次 1是2次一次类推
                valueAnimator.setRepeatCount(-1);
                // 动画的下次执行开始位置,RESTART表示动画每次从原始的状态执行,
                // REVERSE表示动画第二次执行要从第一次改变后的状态逆向执行
                valueAnimator.setRepeatMode(ValueAnimator.RESTART);
                // 设置数值变化监听器,
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        // 获取当前变化的值
                        int currentValue = (Integer) valueAnimator.getAnimatedValue();
                        textView.setBackgroundColor(currentValue);
                    }
                });
                // 开始动画
                valueAnimator.start();

猜你喜欢

转载自blog.csdn.net/qq_33210042/article/details/107912894