[[438230]] Preface Property animation can animate a certain property, and the interpolator (TimeInterpolator) and estimator (TypeEvaluator) play an important role in it; So today we will learn about the interpolator TimeInterpolator; 1. Introduction to interpolators 1. What is Interpolator used for?- Interpolator is used to modify the animation effect and define the rate of change of the animation;
- The corresponding interface class in the Android source code is TimeInterpolator, which inputs a uniformly changing value between 0 and 1;
- You can get the change curves between 0 and 1 such as uniform speed, positive acceleration, negative acceleration, and irregular acceleration;
2. Application scenarios- Achieve animation effects of non-linear motion;
- Non-linear motion means that the rate of change of animation is not constant, such as the animation effects of acceleration and deceleration;
- Custom interpolators are required to implement complex curve animations, customize rebound effects, etc.
3. Interpolator types provided by the Android system- AccelerateDecelerateInterpolator is slow at the beginning and end of the animation, and accelerates in the middle
- AccelerateInterpolator
- AnticipateInterpolator starts backwards and then swings forward
- AnticipateOvershootInterpolator starts by going backwards and then forwards a certain value before returning to the final value.
- BounceInterpolator bounces when the animation ends
- CycleInterpolator The animation loops a specific number of times, with the rate changing along a sine curve.
- DecelerateInterpolator
- LinearInterpolator changes at a constant rate
- OvershootInterpolator throws forward a certain value and then returns to the original position
2. Interpolator Application There are two ways to use interpolators: in XML and in code 1. xml When using an interpolator in an XML animation file, you need to set the corresponding interpolator resource ID set by the system. - <?xml version= "1.0" encoding= "utf-8" ?>
- < set xmlns:android= "http://schemas.android.com/apk/res/android" >
- <alpha
- android:fromAlpha= "1.0"
- android:toAlpha= "0.1"
- android:duration= "2000"
- android:repeatMode= "reverse"
- android:repeatCount= "infinite"
- android:interpolator= "@android:anim/linear_interpolator" />
- </ set >
2. Use in code- When the code uses an interpolator, you only need to create the corresponding interpolator object and then set it to the animation object; you can also load the interpolator configured in the XML file;
- Use the view's setInterpolator(Context context, @AnimRes @InterpolatorRes int resID) to set the interpolator;
- //Create a gradient transparency animation from transparent to fully opaque
- AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
- //Set animation duration
- alphaAnimation.setDuration(5000);
- //Set the animation repeat mode
- alphaAnimation.setRepeatMode(AlphaAnimation.REVERSE);
- //Set the number of animation plays
- alphaAnimation.setRepeatCount(AlphaAnimation.INFINITE);
- //Set the uniform speed interpolator
- alphaAnimation.setInterpolator(new LinearInterpolator());
- // Enable the specified type of animation for View
- imageView.startAnimation(alphaAnimation)
- Using Android's built-in interpolator can meet most animation needs;
- If the interpolator provided by the system cannot meet your needs, you can also customize the interpolator;
3. Custom Interpolator 1. Implementation- Custom interpolators need to implement the Interpolator or TimeInterpolator interface and override the getInterpolation() method;
- Tween animation implements Interpolator interface; property animation implements TimeInterpolator interface;
- The TimeInterpolator interface is newly added in property animation to be compatible with the Interpolator interface, which allows all previous Interpolator implementation classes to be used directly in property animation;
The Interpolator interface and TimeInterpolator interface are described as follows: - //Interpolator interface
- public interface Interpolator {
- // There is only one method inside: getInterpolation()
- float getInterpolation( float input) {
- // Parameter description
- // The input value range is 0-1, and changes evenly with the animation progress (0% - 100%)
- // When the animation starts, the input value = 0; when the animation ends, the input = 1
- // The middle value increases evenly between 0 and 1 as the animation progresses (0% - 100%)
- ...// Interpolator calculation logic
- return xxx;
- // The returned value is the fraction value used by the estimator to continue calculating, which will be explained in detail below
- }
- // TimeInterpolator interface
- public interface TimeInterpolator {
- float getInterpolation( float input){
- // The input value range is 0-1, and changes evenly with the animation progress (0% - 100%)
- ...// Interpolator calculation logic
- };
- }
The key to custom interpolators is to calculate the percentage of the current property value change through logical calculations based on the progress of the animation (0%-100%). 2. Custom interpolator Write a custom Interpolator: decelerate first and then accelerate - /*
- * Implement Interpolator interface as required
- * TestInterpolator.java
- */
- public class TestInterpolator implements TimeInterpolator {
- @Override
- public float getInterpolation( float input) {
- float result;
- if (input <= 0.5) {
- result = ( float ) (Math.sin(Math.PI * input)) / 2;
- // Use the sine function to achieve the function of deceleration first and then acceleration. The logic is as follows:
- // Because the initial radian change of the sine function is very large, it is exactly the opposite of the cosine function
- // As the radian increases, the change value of the sine function will gradually decrease, thus achieving the effect of deceleration.
- // When the radian is greater than π/2, the whole process is reversed. Now the radian change value of the sine function is very small. As the radian continues to increase, the change value becomes larger and larger, and ends when the radian reaches π. In this way, the transition from 0 to π achieves the effect of deceleration first and then acceleration.
- } else {
- result = ( float ) (2 - Math.sin(Math.PI * input)) / 2;
- }
- return result;
- // The returned result value = the animation progresses with a trend of first slowing down and then accelerating
- }
- }
- /*
- * Steps to set up use
- * Test.java
- */
- // Create an animation object: Here we take Button as an example
- mButton = (Button) findViewById(R.id.Button);
- // Get the current button position
- float curTranslationX = mButton.getTranslationX();
- // Create animation object & set animation
- ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "translationX" , curTranslationX, 300,curTranslationX);
- // means:
- // The animation object is mButton
- // The property of the object being animated is X-axis translation
- // The animation effect is: moving from the current position to x=1500 and then moving to the initial position
- // Set the interpolator set in step 1: decelerate first and then accelerate
- animator.setInterpolator(new TestInterpolator());
- // Start the animation
- animator.start();
3. Bezier curve interpolator (1) First use the Bezier curve value generation tool to obtain the desired curve value - Tool website: https://cubic-bezier.com/;
- Drag the two points on the left image to adjust the graphics to meet the effect;
- Click the Go button to see the movement of the red and blue blocks and adjust the effect you want;
- Apply the 4 parameters to the following code;
(2) Code application - ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "translationX" , curTranslationX, 300,curTranslationX);
- EaseCubicInterpolator interpolator = new EaseCubicInterpolator(0.31f, 0.85f,0.77f, 0.14f);
- animator.setInterpolator(interpolator)
(3) Bezier curve interpolator - import android.graphics.PointF;
- import android.view.animation.Interpolator ;
- /**
- * Easing cubic curve interpolator. (Based on cubic Bezier curve)
- */
- public class EaseCubicInterpolator implements Interpolator {
- private final static int ACCURACY = 4096;
- private int mLastI = 0;
- private final PointF mControlPoint1 = new PointF();
- private final PointF mControlPoint2 = new PointF();
- /**
- * Set the two middle control points
- *
- * Online tool: http://cubic-bezier.com
- *
- * @param x1
- * @param y1
- * @param x2
- * @param y2
- */
- public EaseCubicInterpolator( float x1, float y1, float x2, float y2) {
- mControlPoint1.x = x1;
- mControlPoint1.y = y1;
- mControlPoint2.x = x2;
- mControlPoint2.y = y2;
- }
- @Override
- public float getInterpolation( float input) {
- float t = input;
- // Approximately solve the value of t [0,1]
- for ( int i = mLastI; i < ACCURACY; i++) {
- t = 1.0f * i / ACCURACY;
- double x = cubicCurves(t, 0, mControlPoint1.x, mControlPoint2.x, 1);
- if (x >= input) {
- mLastI = i;
- break;
- }
- }
- double value = cubicCurves(t, 0, mControlPoint1.y, mControlPoint2.y, 1);
- if (value > 0.999d) {
- value = 1;
- mLastI = 0;
- }
- return ( float ) value;
- }
- /**
- * Find the value of a certain dimension of a point on a cubic Bezier curve (four control points).<br>
- * <p>
- *
- * @param t value [0, 1]
- * @param value0
- * @param value1
- * @param value2
- * @param value3
- * @return
- */
- public static double cubicCurves( double t, double value0, double value1,
- double value2, double value3) {
- double value;
- double u = 1 - t;
- double tt = t * t;
- double uu = u * u;
- double uuu = uu * u;
- double ttt = tt * t;
- value = uuu * value0;
- value += 3 * uu * t * value1;
- value += 3 * u * tt * value2;
- value += ttt * value3;
- return value;
- }
- }
Summarize To achieve complex animation effects, you need to customize the interpolator. In fact, the interpolator is still a learning algorithm; Let's all cheer together; |