Android animation is owned by Catango
preface
Animation effect has always been a very important part of human-computer interaction. The introduction of animation effect will make the interaction more friendly and make users get a more pleasant experience. As a front-end developer, animation is also a must-have skill.
View Animation
View Animation includes Tween Animation and Frame Animation (Drawable Animation). These are the two kinds of animations before Android 3.0.
The frame of animation
A frame animation, sometimes called a Drawable animation, allows you to perform slideshows. This animation is actually a Drawable, so the XML definition file for this animation is usually in the RES/Drawable/directory. The essence of frame animation is our visual residue.
We usually refer to the animation resource under Drawable, and then call start()/stop() in code to start or stop the animation. We can also create a frame-by-frame animation in Java code, create an AnimationDrawable object, and then call addFrame(Drawable Frame,int Duration) to add frames to the animation. Start () and stop() are then called ~ XML is recommended to define the animation.
Specific labels are:
<animation-list>
: Must be the root node, which contains multiple nodes< item>
Elements. Properties include Android :oneshot true for once, false for loop.< item>
:a child of animation-list, containing the following attributes:- Android :drawable The drawable resource of a frame.
- Android :duration Indicates how long a frame is.
So for example, we’re in drawable
< ?xml version="1.0" encoding="utf-8"? > < animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
< item android:drawable="@color/black" android:duration="300"/>
< item android:drawable="@color/white" android:duration="300"/>
< /animation-list>Copy the code
And then in Kotlin
img_test.apply {
setBackgroundResource(R.drawable.test_frame)
setOnClickListener {
if ((background as AnimationDrawable).isRunning)
(background as AnimationDrawable).stop()
else (background as AnimationDrawable).start()
}
}Copy the code
This will automatically play the resource set in drawable when we click on the image. Note that the Animation’s start method cannot be called in the Activity’s onCreate method because the AnimationDrawable is not fully attached to the Window.
Filling between animation
Tween Animation applies only to View objects and only supports some properties, such as zooming and rotation, but not background color changes. And for the Tween Animation, it doesn’t change the property value, it just changes the position of the View object, it doesn’t change the View object itself, for example, you have a Button, coordinates (100,100), Width:100,Height:100, And you have an animation that moves it (200,200), and you see that the area that triggers the button click during the animation is still (100,100)-(200,200).
Tween animations are defined in XML or Android code, but XML files are recommended because they are more readable and reusable. It is the parent of all tween animation classes:
public abstract class Animation implements CloneableCopy the code
This note is distinguished from the parent class of the property animation.
The Java class name | XML keyword | Description information |
---|---|---|
AlphaAnimation | Place it in the res/anim/ directory | Gradient transparency animation effect |
RotateAnimation | Place it in the res/anim/ directory | Screen transfer rotation animation effect |
ScaleAnimation | Place it in the res/anim/ directory | Tween size scaling animation effect |
TranslateAnimation | Place it in the res/anim/ directory | Screen shift position move animation effect |
AnimationSet | Place it in the res/anim/ directory | A container that holds other animation elements alpha, scale, Translate, rotate, or other set elements |
Animation attributes
XML attributes | Java method | explain |
---|---|---|
android:detachWallpaper | setDetachWallpaper(boolean) | Whether to run on wallpaper |
android:duration | setDuration(long) | Animation duration in milliseconds |
android:fillAfter | setFillAfter(boolean) | Control whether the last state of the animation remains when the animation ends |
android:fillBefore | setFillBefore(boolean) | Control whether the animation ends in the state before the animation began |
android:fillEnabled | setFillEnabled(boolean) | The same effect as Android :fillBefore |
android:interpolator | setInterpolator(Interpolator) | Set interpolators (specify animation effects, such as rebound, etc.) |
android:repeatCount | setRepeatCount(int) | Repeat the number |
android:repeatMode | setRepeatMode(int) | The repeat type has two values: Reverse for playback in reverse order and restart for playback from the beginning |
android:startOffset | setStartOffset(long) | The time, in milliseconds, to wait to start running after calling the start function |
android:zAdjustment | setZAdjustment(int) | Represents the position on the Z-axis (top/bottom/normal) where the content is animated when it runs. The default is normal |
Alpha attribute
XML attributes | Java method | explain |
---|---|---|
android:fromAlpha | AlphaAnimation (float fromAlpha,…). | Opacity at the beginning of the animation (0.0 to 1.0, 0.0 is fully transparent, 1.0 is opaque) |
android:toAlpha | AlphaAnimation (… , float toAlpha) | Opacity at the end of the animation, ditto |
Rotate the attribute
XML attributes | Java method | explain |
---|---|---|
android:fromDegrees | RotateAnimation (float fromDegrees,…). | Rotation Angle, positive represents clockwise degrees, negative represents counterclockwise degrees |
android:toDegrees | RotateAnimation (… The float toDegrees,…). | Rotation end Angle, positive represents clockwise degrees, negative represents counterclockwise degrees |
android:pivotX | RotateAnimation (… The float pivotX,…). | Scale the starting X coordinate (value, percentage, percentage P, for example, 50 means the top left coordinate of the current View plus 50px as the initial point, 50% means the top left corner of the current View plus 50% of the width and height of the current View as the initial point, 50% P means the top left corner of the current View plus 50% of the width and height of the parent control as the initial point) |
android:pivotY | RotateAnimation (… , float pivotY) | Scale the starting Y coordinate, same as above |
Scale properties
XML attributes | Java method | explain |
---|---|---|
android:fromXScale | ScaleAnimation (float fromX,…). | Initial X-axis scaling, 1.0 means no change |
android:toXScale | ScaleAnimation (… , float toX,…). | End X-axis scaling |
android:fromYScale | ScaleAnimation (… The float fromY,…). | Initial Y scale |
android:toYScale | ScaleAnimation (… The float toY,…). | End Y axis scaling |
android:pivotX | ScaleAnimation (… The float pivotX,…). | Scale the starting X-axis coordinates (value, percentage, percentage P, for example, 50 means the top left coordinate of the current View plus 50px as the initial point, 50% means the top left corner of the current View plus 50% of the width and height of the current View as the initial point, 50% P means the top left corner of the current View plus 50% of the width and height of the parent control as the initial point) |
android:pivotY | ScaleAnimation (… , float pivotY) | Scale the Y coordinates of the starting point, as above |
Detailed explanation of the Translate attribute
XML attributes | Java method | explain |
---|---|---|
android:fromXDelta | TranslateAnimation (float fromXDelta,…). | X-axis coordinates of the starting point (value, percentage, percentage P, for example, 50 means the starting point with the coordinate of the upper left corner of the current View plus 50px; 50% means the starting point with the upper left corner of the current View plus 50% of the width and height of the current View; 50% P means the starting point with the upper left corner of the current View plus 50% of the width and height of the parent control) |
android:fromYDelta | TranslateAnimation (… , float fromYDelta,…). | Same rule as above |
android:toXDelta | TranslateAnimation (… , float toXDelta,…). | The x-coordinate of the end point is the same as above |
android:toYDelta | TranslateAnimation (… , float toYDelta) | The y-coordinate of the end point is the same as above |
interpolator
Interpolator Interpolator is used to control the change rate of an animation. We can Interpolator interface ourselves to control the change rate of an animation. Android has five Interpolator classes available:
- LinearInterpolator: The animation changes at a uniform speed
- AccelerateInterpolator: Changes slowly at the beginning of an animation, then begins to accelerate
- AccelerateDecelerateInterpolator: at the beginning of the animation, the end of the local change slower, middle speed
- CycleInterpolator: Animation is looped a specific number of times at a sinusoidal speed: math.sin (2 mCycles Math.PI * input)
- Activity: Change fast at the beginning of the animation, then slow down
- AnticipateInterpolator: reverse, making a paragraph change in the opposite direction before accelerating playback
- AnticipateOvershootInterpolator: at the start of the backward and forward to jilt a certain value returns the value of the final
- BounceInterpolator: jumps. A value will jump when approaching a destination value, such as the destination value 100. Subsequent values may be 85,77,70,80,90,100
- OvershottInterpolator: interpolates back, eventually exceeding the target value and then slowly changing to the target value
Introduction to Use:
Above these are some XML and Java methods of tween animation introduction, these method attributes do not remember it does not matter, we can view at any time, the most important or how to use. In fact, the usage is also very simple, very routine, we just need to remember the routine can. Let’s take a simple example of rotating animation.
The first is the XML
< ?xml version="1.0" encoding="utf-8"? > < rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
/>Copy the code
Animation activity @ Android: Animaccelerate_theme ator is the interpolator that will change at the beginning of the animation and then slow down.
After writing the XML, in the Java code
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate);
testImg.setAnimation(animation);
animation.start();
animation.cancel();Copy the code
We can see that we first create an Animation object and then load the Animation defined in the XML into the Animation object using the loadAnimation method of AnimationUtils. We then pass in the animation via the View setAnimation method, which binds the animation to the View. Finally, the animation is started or cancelled using the animation’s start and cancel methods. We can set the listener for the animation.
Property Animation
Android 3.0 introduced property animation, property animation can easily achieve a lot of View animation can not do. In fact, remember a point on the line, the principle of property animation is to modify the control of the property value of the animation. Of course, the price of power is complexity to use.
All the parent classes of the property animation are it:
public abstract class Animator implements CloneableCopy the code
This note is distinguished from the tween animation.
Here are the related apis:
- The Animator creates the base class for property animations, usually using two of its subclasses rather than directly
- ValueAnimator The direct derived class of an Animator. It uses a time-loop mechanism to calculate the animation transition between values. We only need to provide the initial value and the end value to the class, and tell the length of time required for the animation, and the class will automatically help us smooth the transition from the initial value to the end. This class also manages playback times, modes, listeners, and so on.
- AnimatorSet A direct derivative of an Animator that can combine multiple animators and specify the order in which the animators are played.
- ObjectAnimator, a subclass of ValueAnimator, allows us to animate properties of specified objects.
- Evaluator calculator, which tells the animation system how to transition from initial to final values. The following evaluators are available:
- IntEvaluator: Used to calculate an int attribute
- FloatEvaluator: Used to evaluate float properties
- ArgbEvaluator: calculator used to calculate the value of a hexadecimal representation color
- TypeEvaluator: A public interface for the computation classes described above. You can customize the interface yourself.
ValueAnimator
Use process:
- Call ValueAnimator’s ofInt(), ofFloat(), or ofObject() static methods to create a ValueAnimator instance
- Call the setXxx method of the instance to set the animation duration, interpolation method, repetition number, etc
- Call the instance’s addUpdateListener to add the AnimatorUpdateListener listener. In this listener, you can get ValueAnimator values that you can apply to the specified object
- Call the instance’s start() method to start the animation! We can also see that both ofInt and ofFloat have a float/int… Values stand for multiple values!
Here’s an example:
// Move according to the trajectory equationlineAnimator() {
width = ly_root.getWidth();
height = ly_root.getHeight();
ValueAnimator xValue = ValueAnimator.ofInt(height,0,height / 4,height / 2,height / 4 * 3 ,height);
xValue.setDuration(3000L);
xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@override public void onAnimationUpdate(ValueAnimator animation) { animation.getAnimatedValue(); int x = width / 2; moveView(img_babi, x, y); }}); xValue.setInterpolator(new LinearInterpolator()); xValue.start(); } private void moveView(View view, int rawX, int rawY) { int left = rawX - img_babi.getWidth() / 2; int top = rawY - img_babi.getHeight(); int width = left + view.getWidth(); int height = top + view.getHeight(); view.layout(left, top, width, height); }Copy the code
The moveView method rearranges the View, the value of xValue can be seen from the argument list, and then sets the listener for each update. In this listener, moveView method is called each time to change the View layout. For composite animation, we could do this:
// Zoom effect private voidscaleAnimator(){
final floatScale = 0.5 f; AnimatorSet scaleSet = new AnimatorSet(); ValueAnimatorSmall = ValueAnimator.offloat (1.0f, scale); valueAnimatorSmall.setDuration(500); ValueAnimatorLarge = Valueanimator.offloat (scale, 1.0f); valueAnimatorLarge.setDuration(500); valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
floatscale = (Float) animation.getAnimatedValue(); img_babi.setScaleX(scale); img_babi.setScaleY(scale); }}); valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
floatscale = (Float) animation.getAnimatedValue(); img_babi.setScaleX(scale); img_babi.setScaleY(scale); }}); scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall); scaleSet.start(); }Copy the code
For this composite animation, we can set the animation instance with play After, and then the animation executes the play animation and then the after instance. Of course, there is a similar method called with, where the two animations will play together.
- After (Animator anim) inserts the existing animation after the incoming animation
- After (long delay) Executes the existing animation after the specified millisecond delay
- Before (Animator anim) inserts an existing animation before the incoming animation
- With (Animator anim) executes an existing animation and an incoming animation simultaneously
ObjectAnimator
ObjectAnimator is probably the most commonly encountered class compared to ValueAnimator, because ValueAnimator does nothing more than a smooth animation transition to a value, but we don’t really use this feature in many situations. ObjectAnimator, on the other hand, can animate any property of any object directly, such as the Alpha property of a View. ObjectAnimator is not designed for a View, but for any object.
Since ObjectAnimator inherits from ValueAnimator, its usage should be similar to ValueAnimator.
ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f);Copy the code
ObjectAnimator will help us change the alpha property of our TextView object from 1F to 0F. The TextView object then needs to constantly refresh the display of the interface based on changes in the alpha property value, so that the user can see how the animation fades in and out.
So does the textView object have an alpha property? No, not only does TextView not have this property, but all of its parent classes don’t have this property either! Textview does not have an alpha property, so how does ObjectAnimator operate? ObjectAnimator does not directly operate on the property name we pass in. Instead, ObjectAnimator looks for the get and set methods that correspond to the property name.
public void setAlpha(float value);
public float getAlpha();Copy the code
ObjectAnimator is much easier to use than ValueAnimator, we only need to instantiate it, other uses are the same as ValueAnimator.
Monitor for animation
AnimatorUpdateListener is the listener for ValueAnimator. It calls onAnimationUpdate when the value state changes. In addition to these events: AnimatorListener, we can call the addListener method to add listeners, and then override the following four callback methods:
- OnAnimationStart () : Animation starts
- OnAnimationRepeat () : Animation is repeated
- OnAnimationEnd () : Animation ends
- OnAnimationCancel () : Animation cancelled
To add an AnimatorListener, you’ll need to override all four methods, which is a hassle to write, but Android already provides an adapter class: AnimatorListenerAdapter, which already implements every interface method, so we can just write one callback method here.
Evaluator
We use static methods ofInt,ofFloat, and ofObject to create instances of ValueAnimator when we invoke property animations. In this example, we use ofInt,ofFloat. ValueAnimator also has an ofObject method to construct ValueAnimator instances. What does this do?
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}Copy the code
Let’s poke in and look at the source parameters. The first parameter is something called TypeEvaluator, which is the calculator that tells the animation system how to transition from an initial value to an end value. As mentioned earlier, TypeEvaluator is the base class for all evaluators. Again, the system provides the following types of evaluators:
- IntEvaluator: Used to calculate an int attribute
- FloatEvaluator: Used to evaluate float properties
- ArgbEvaluator: calculator used to calculate the value of a hexadecimal representation color
- TypeEvaluator: A public interface for the computation classes described above. You can customize the interface yourself.
Of course, these evaluators are TypeEvaluator implementations. Let’s start with what the TypeEvaluator interface looks like:
public interface TypeEvaluator<T> {
public T evaluate(float fraction, T startValue, T endValue);
}Copy the code
This is the evaluate method, simple? The meanings of the three parameters are as follows:
- Fraction: The completion of the animation. We use this to calculate the value of the animation
- StartValue: indicates the startValue of the animation
- EndValue: endValue of the animation
TypeEvaluator is an interface that implements TypeEvaluator. IntEvaluator implements TypeEvaluator.
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return(int)(startInt + fraction * (endValue - startInt)); }}Copy the code
The TypeEvaluator interface is implemented and the Evaluate method is overridden, which returns the value of the animation. What is the value of the animation? IntEvaluator returns the value of the animation = initial + completion * (End – initial) so that when completion is 100%, the value of the animation is the end value. As you’ll notice, the TypeEvaluator is passing in a generic type, which we’ll define as Object.
Now let’s take the example of a custom Evaluator.
package com.example.yang.testkotlin.widget; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; 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.graphics.Point; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; /** * @author YangCihang * @since 17/10/18. * email [email protected] */ public class CircleAnimView extends View { public static final int RADIUS = 80; private Point currentPoint; private Paint mPaint; private int mColor; // We must write the get and the attributesetPublic CircleAnimView(Context Context) {super(Context); } public CircleAnimView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public CircleAnimView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private voidinit() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas) {
if (currentPoint == null) {
currentPoint = new Point(RADIUS, RADIUS);
drawCircle(canvas);
startAnimation();
} else {
drawCircle(canvas);
}
}
private void drawCircle(Canvas canvas) {
float x = currentPoint.x;
floaty = currentPoint.y; DrawCircle (x, y, RADIUS, mPaint); drawCircle(x, y, RADIUS, mPaint); } private voidstartAnimation() {
Point startPoint = new Point(RADIUS, RADIUS);
Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { currentPoint = (Point) animation.getAnimatedValue(); invalidate(); }}); ObjectAnimator objectAnimator = ObjectAnimator.ofObject(this,"color", new ColorEvaluator(), Color.BLUE, Color.RED); AnimatorSet AnimatorSet = new AnimatorSet(); animatorSet.play(anim).with(objectAnimator); animatorSet.setStartDelay(1000L); animatorSet.setDuration(3000L); animatorSet.start(); } / / PointEvaluator implements TypeEvaluator<Point> {@override public Point evaluate(floatfraction, Point startValue, Point endValue) {// endValue + endValue * (endValue. X + startValue. X); int y = (int) (startValue.y + fraction * (endValue.y - startValue.y));returnnew Point(x, y); Public implements TypeEvaluator<Integer> {public implements TypeEvaluator<Integer>float fraction, Integer startValue, Integer endValue) {
int alpha = (int) (Color.alpha(startValue) + fraction *
(Color.alpha(endValue) - Color.alpha(startValue)));
int red = (int) (Color.red(startValue) + fraction *
(Color.red(endValue) - Color.red(startValue)));
int green = (int) (Color.green(startValue) + fraction *
(Color.green(endValue) - Color.green(startValue)));
int blue = (int) (Color.blue(startValue) + fraction *
(Color.blue(endValue) - Color.blue(startValue)));
returnColor.argb(alpha, red, green, blue); }} //color get andsetMethod ~ public intgetColor() {
return mColor;
}
public void setColor(int color) { mColor = color; mPaint.setColor(color); invalidate(); }}Copy the code
Here we define two Evaluator classes to represent coordinate changes and color changes respectively. Note that when we want to change the color property, we must write setColor and getColor methods, for the reasons explained above.
Interpolator
Interpolator is called Interpolator or Interpolator. In tween animation we introduced a few common interpolators that we can go back to. Both tween animation and property animation can use interpolators. Interpolator interface is Interpolator interface. Interpolator interface is Interpolator interface. Interpolator interface is Interpolator interface. This makes all past Interpolator implementation classes Interpolator can be used directly in a property animation! We can set different interpolators by calling the setInterpolator() method of an animation object. Such as:
animatorSet.setInterpolator(new AccelerateInterpolator(2f))Copy the code
The values in parentheses are used to control the acceleration.
Custom Interpolator
Interpolator is Interpolator; Interpolator is Interpolator; Interpolator is Interpolator; Interpolator is Interpolator; Interpolator is Interpolator.
private class DecelerateAccelerateInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
if (input < 0.5) {
return (float) (Math.sin(input * Math.PI) / 2);
} else {
return 1 - (float) (Math.sin(input * Math.PI) / 2); }}}Copy the code
But if we’re going to do some complicated rate changes, we’re going to need some math.