Attribute animation of Android animation series

Attribute animation is more powerful than frame animation and gap animation. Frame animation and gap animation can only be applied to view and its subclasses. Attribute animation can modify the attribute value of any object, and the attribute value can be changed automatically within a specified period of time to realize more complex animation according to the change of object attribute value.

The following are common settings for attribute animation, as follows:

//设置属性动画持续时间
animator.setDuration(2000);
//设置属性插值器
animator.setInterpolator(new AccelerateInterpolator());
//设置属性动画重复播放模式
animator.setRepeatMode(ValueAnimator.REVERSE);
//设置属性动画重复播放次数
animator.setRepeatCount(0);
//设置属性动画延时播放的时间
animator.setStartDelay(0);
//设置属性动画估值器,用于控制最终属性值(API22)
animator.setCurrentFraction(0.5f);
//设置当前播放时间,其值在Duration范围之内
animator.setCurrentPlayTime(1000);
//设置属性动画估值器,用于控制最终属性值
animator.setEvaluator(new IntEvaluator());
//设置属性动画监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.i(TAG,animation.getAnimatedValue() + "");
        //
    }
});
//...

Valueanimator provides a simple timing engine, which is used to complete the calculation of animation values according to the set duration and other attributes when executing animation, and then set the animation values to appropriate target objects. The interpolator used is acceleratedeelerateinterpolator by default, which means that the animation is slow at the beginning and end, and the animation is accelerated in the middle, The following is the default interpolator in the source code, as follows:

// The time interpolator to be used if none is set on the animation
private static final TimeInterpolator sDefaultInterpolator =
        new AccelerateDecelerateInterpolator();

In valueanimator, some evaluators intevaluator and floatevaluator have been processed internally, that is, if the ofint and ofFloat methods are used as the attribute values of animation, valueanimator will automatically process the changes of int and float values. Find it in the source code. This part is in the propertyvaluesholder class, as follows:

void init() {
    if (mEvaluator == null) {
        // We already handle int and float automatically,but not their Object
        // equivalents
        mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
                (mValueType == Float.class) ? sFloatEvaluator :
                null;
    }
    if (mEvaluator != null) {
        // KeyframeSet kNows how to evaluate the common types - only give it a custom
        // evaluator if one has been set on this class
        mKeyframes.setEvaluator(mEvaluator);
    }
}

Valueanimator can be created in code or XML. The following takes translation animation as an example to illustrate the use of valueanimator, which is similar to other use methods such as scaling and rotation.

private void translation(){
    ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
    valueAnimator.setDuration(2000);
    valueAnimator.setInterpolator(new AccelerateInterpolator());
    valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
    valueAnimator.setRepeatCount(0);
    valueAnimator.setStartDelay(0);
//    valueAnimator.setCurrentFraction(0.5f);
//    valueAnimator.setCurrentPlayTime(1000);
    valueAnimator.setEvaluator(new IntEvaluator());

    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG,animation.getAnimatedValue() + "");
            int x = (int) animation.getAnimatedValue();
            ivImage.setTranslationX(x);
            ivImage.setTranslationY(x);
        }
    });

    valueAnimator.start();
}

Create a test in the RES / Animator folder_ Animator.xml file, the contents of which are as follows:

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:valueFrom="0"
    android:valueTo="100"
    android:valueType="intType"

    android:duration="2000"
    android:startOffset ="0"
    android:repeatMode = "reverse"
    android:repeatCount = "0"
    android:interpolator = "@android:anim/accelerate_interpolator">
</animator>

Then get valueanimator in activity, set the target object and start the animation, as follows:

private void translation(){
    ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.test_animator);
    animator.setTarget(ivImage);
    animator.start();
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG,animation.getAnimatedValue() + "");
            int x = (int) animation.getAnimatedValue();
            ivImage.setTranslationX(x);
            ivImage.setTranslationY(x);
        }
    });
}

Here, valueanimator is used to realize translation animation. The test results are as follows:

Objectanimator is a subclass of valueanimator, which can support the setting of animation attributes on the target object. In its construction method, specify the name of the target object and the corresponding animation attribute through parameters, and then execute the setter method of the corresponding animation attribute accordingly to finally complete the execution of animation, In other words, the objectanimator finally calls the setter method of the target object to change the attribute value of the target object, and then changes the attributes of the target object accordingly to achieve the animation effect of the target object. The following describes the basic use of objectanimator with the change of transparency. The code reference is as follows:

private void alpha(){
    ObjectAnimator animator = ObjectAnimator.ofFloat(ivImage,"alpha",1f,1f);
    animator.setDuration(3000);
    //其他属性动画设置
    //...
    animator.start();
}

The following is the test effect, as shown in the figure below:

The implementation methods of translation, rotation and scaling animation are basically the same as above, which will not be repeated here. The corresponding relationship of the corresponding setter method is as follows:

Objectanimator provides many ofXXX () methods to animate attributes, as shown in the following figure:

The objectvalueanimator ofxxx() method can be used to realize the corresponding animation according to different animation requirements.

Here is a brief introduction to the use of keyframes. As the name suggests, keyframes are defined as specific attribute values at a fixed time. For defined, attribute values will be returned according to the values returned by the estimator. The use of keyframes in attribute animation is as follows:

/**
 * 关键帧的使用
 */
private void keyFrame(){
    Keyframe keyframe1 = Keyframe.ofFloat(0,0);
    Keyframe keyframe2 = Keyframe.ofFloat(0.25f,300);
    //每个KeyFrame可设置自己的插值器
    keyframe2.setInterpolator(new AccelerateInterpolator());
    Keyframe keyframe3 = Keyframe.ofFloat(0.75f,100);
    Keyframe keyframe4 = Keyframe.ofFloat(1,400);
    PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX",keyframe1,keyframe2,keyframe3,keyframe4);
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(ivImage,holder);
    animator.setDuration(3000);
    animator.start();
}

Take a look at the changes to the normal translation animation after adding key frames. The test results are as follows:

Android has many built-in interpolators, which basically cover most situations in actual development, as follows:

If the built-in interpolator does not meet the requirements, you can also customize the interpolator.

Here, customize an estimator to realize a view moving along a sinusoidal curve. The customized estimator is as follows:

/**
 * 自定义估值器
 * Point封装了坐标x和y
 */
public class SineTypeValue implements TypeEvaluator<Point> {
    @Override
    public Point evaluate(float fraction,Point startValue,Point endValue) {
        //y = sinA
        float distance = fraction * (endValue.getX() - startValue.getX());
        float x = startValue.getX() + distance;
        float y = startValue.getY() + (float) Math.sin(distance / 100 * Math.PI) * 100;
        Point point = new Point();
        point.setX(x);
        point.setY(y);
        return point;
    }
}

Then set the estimator for the animation, monitor the animation properties, and set the position of the view to realize a view moving along a sinusoidal curve. The usage is as follows:

/**
 * 自定义估值器的使用
 * 正弦运动的估值器
 */
private void sina(){
    Point startPoint = new Point(ivImage.getX(),ivImage.getY());
    Point endPoint = new Point(ivImage.getX()+500,ivImage.getY());
    ValueAnimator valueAnimator = ValueAnimator.ofObject(new SineTypeValue(),startPoint,endPoint);
    valueAnimator.setDuration(5000);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG,animation.getAnimatedValue() + "");
            Point point = (Point) animation.getAnimatedValue();
            ivImage.setX(point.getX());
            ivImage.setY(point.getY());
        }
    });
    valueAnimator.start();
}

The test results are as follows:

We can pay attention to the official account: jzman-blog and exchange learning.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>