Many apps on the market use animation effects, and good animation effects can improve the user experience. So what animation mechanisms does the Android system have?
1. Frame-by-frame animation. The working principle of frame-by-frame animation is very simple. In fact, it is to split a complete animation into separate pictures, and then connect them together for playback, similar to the working principle of cartoons.
2. Tweened animation allows you to perform a series of animation operations on View, including fade in and fade out, scaling, translation, and rotation.
3. Property Animation Property Animation can achieve more dazzling animation effects by changing the properties of objects.
1. Tweening animation only changes the position and realistic effect of the View, but cannot change its attributes. For example, if a Button is moved using tweening animation and then clicked again, it will not respond to the click event, but attribute animation can do this.
2. The objects of tweening animation are only limited to View, while the objects of attribute animation are not limited to View, but affect all objects. For example: attribute animation can change the color value, but tweening animation cannot do this.
ValueAnimator is an important class in attribute animation. It uses a time loop mechanism internally to calculate the animation transition between values. We only need to change the initial value and the end value are provided to ValueAnimator, and tell it how long the animation needs to run, then ValueAnimator will automatically help us complete the smooth transition from the initial value to the end value. Let's take a look at its usage through an example. The usage of ValueAnimator is very simple:
private void startAnimation() { ValueAnimator animator = ValueAnimator.ofInt(0, 20,0); //为了看到动画值的变化,这里添加了动画更新监听事件来打印动画的当前值 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); Log.e("TAG", "the value is " + value); } }); animator.setDuration(1000);//动画时间 animator.start();//启动动画 }
ValueAnimator ofInt (int... values); There can be one or more parameters. However, there are usually more than two. If it is represented by two parameters: the value changes from the first parameter to the second parameter over time. If there are more than three parameters: changes over time between these values. Look at the above print result as follows:
ValueAnimator has other methods. For example, if you need an animation change of floating point data, you can use the following:
ValueAnimator animator = ValueAnimator.ofFloat(0f,10.5f,5.0f,0f); animator.setDuration(500);//动画时间 animator.start();//启动动画
Change the color value Animation
ValueAnimator animator = ValueAnimator.ofArgb(0x00ffff,0x00ffee); animator.setDuration(500);//动画时间 animator.start();//启动动画
Animation that changes a generic value ValueAnimator animator = ValueAnimator.ofObject(). Will talk about it below.
You may be surprised that you didn’t see where it is used in the examples above? Don't worry, let me give you an example to prove its usefulness. Draw a straight line dynamically on the phone screen.
package com.xjp.animations;import android.animation.TypeEvaluator;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewGroup parent = (ViewGroup) findViewById(R.id.parent); parent.addView(new SingleLine(this)); } private class SingleLine extends View { private Paint mPaint; private float x = 0; private float y = 150; public SingleLine(Context context) { super(context); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.RED); } public SingleLine(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.RED); } public SingleLine(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { if (0 == x) { startAnimation(); } canvas.drawLine(0, y, x, x + y, mPaint); } private void startAnimation() { ValueAnimator animator = ValueAnimator.ofObject(new SingleLineEvaluator(), 0, 500); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float i = (float) animation.getAnimatedValue(); x = i; //不断的刷新UI invalidate(); } }); animator.setDuration(2000); animator.start(); } } private class SingleLineEvaluator implements TypeEvaluator { @Override public Object evaluate(float fraction, Object startValue, Object endValue) { return fraction * (((Number) endValue).floatValue() - ((Number) startValue).floatValue()); } }}
We used ValueAnimator animator = ValueAnimator.ofObject (TypeEvaluator evaluator, Object… values). The first parameter of this method is the animation transition algorithm class, and the following parameters are Animation transition value.
Here we mainly explain the TypeEvaluator type: the ofObject() method is different from ofInt() and ofFloat(). You need to implement TypeEvaluator yourself, while the other two method systems help implement their methods, namely the IntEvaluator and FloatEvaluator types.
Take a look at the implementation of FloatEvaluator as follows:
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); }}
As you can see, FloatEvaluator implements the TypeEvaluator interface and then overrides the evaluate() method. Three parameters are passed in to the evaluate() method. The first parameter, fraction, is very important. This parameter is used to indicate the completion of the animation (the value of fraction changes between 0 and 1). We should calculate the current value based on it. What should be the value of the animation? The second and third parameters represent the initial value and end value of the animation respectively. Then the logic of the above code is relatively clear. Subtract the initial value from the end value, calculate the difference between them, then multiply it by the coefficient of fraction, plus the initial value, then you will get the value of the current animation.
Then let’s take a look at the TypeEvaluator we implemented
private class SingleLineEvaluator implements TypeEvaluator { @Override public Object evaluate(float fraction, Object startValue, Object endValue) { return fraction * (((Number) endValue).floatValue() - ((Number) startValue).floatValue()); } }
The interface method evaluate implements the linear straight line algorithm. y=n*x;
There are the following types of built-in TypeEvaluators in the system, which can be used directly in the code.
ArgbEvaluator: This evaluator can be used to perform interpolation between types of integer values representing ARGB colors.
FloatEvaluator: This evaluator can be used to perform interpolation between floating point values.
IntEvaluator: This evaluator can be used to perform interpolation between values of type int.
RectEvaluator: This evaluator can be used to perform interpolation of rectangular values between types.
Next section: Learning ObjectAnimator