Animation summary of android Application Development

Posted by misterph on Wed, 22 May 2019 01:45:27 +0200

Generally speaking, animation will not affect the business logic of our application, but without animation, our application will appear too rigid, no vitality and competitiveness.

The animation in android can be roughly divided into three categories: view animation, frame animation and attribute animation.

Let's start with view animation:

View animation represents a kind of animation inherited from Animation, including translation, zooming, transparency and rotation of view. That is: Translate Animation, Scale Animation, Alpha Animation, Rotate Animation. These four animations can be defined by XML files, such as res/anim/animation.xml, or written in code, but it is much more convenient in XML than in code. Of course, in addition to these four types, we can also use the Animation Set class to combine these four animations. Let's take the definition of XML as an example:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />

</set>

android:shareInterpolator attribute indicates whether the animation shares the same interpolator, interpolator represents the interpolator, and can also pass in an interpolator object through setInterpolator(). Here are some common interpolators:

AccelerateDecelerateInterpolator
Accelerate first and then decelerate. This is the default Interpolator, which means that if you don't set it, the animation will use the Interpolator.

LinearInterpolator
Uniform speed.

AccelerateInterpolator
Continuous acceleration. Throughout the animation process, it has been accelerating until the moment the animation ends, it stops directly.

DecelerateInterpolator
Continue to decelerate until 0. The animation starts at the highest speed, then slows down gradually during the animation process until the animation ends when it just slows down to 0.

AnticipateInterpolator
First pull back a displacement and then proceed to normal animation trajectory.

OvershootInterpolator
The animation will rebound beyond the target area.

AnticipateOvershootInterpolator
Combination of Anticipate Interpolator and Overshoot Interpolator: Pull back before starting, and then bounce back after a period of displacement.

BounceInterpolator
Bounce back and forth in the target area until it stops.

CycleInterpolator
Animation can reach the target area in advance, or rebound after reaching the target area, which is determined by the parameters of the constructor.

PathInterpolator
Path path coordinates represent animation completion/time completion curves. This is a customized animation model, which customizes the relationship between animation completion and time according to the effect you want to achieve. However, it is not allowed to have two animation completion degrees at the same time, otherwise the fc will be reported.

FastOutLinearInInterpolator
Similar to Accelerate Interpolator, it will start accelerating faster and faster, but the difference is small, so it is difficult to find the difference.

FastOutSlowInInterpolator
Similar to Accelerate Decelerate Interpolator, it accelerates first, then decelerates, and the acceleration is greater in both the acceleration and deceleration stages.

LinearOutSlowInInterpolator
Similar to Decelerate Interpolator, it starts to reach the maximum speed and then slows down all the way, but the initial speed will be higher and the deceleration will be faster.

This is a brief introduction to the interpolator.

Loading xml animation is also relatively simple, through the AnimationUtils class to achieve:

  AnimationUtils.loadAnimation(this, R.anim.animation);

Set Animation Listener to set up listeners for Animation:

 animation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

If we want the view to stay at the end of the animation, we can do this by calling fillAfter():

    animation.setFillAfter(true);

However, it should be noted that although view seems to stay at the end of the animation, when we trigger the monitoring event of view, we find that it does not work, but only click on the original location to trigger the monitoring event, which is not android bug, because view animation is only the image of view, and the attributes of view itself have not changed.

In addition, if you need to set the visual property of view at the end of the animation, you need to clear the animation first, otherwise it will not work.

 view.clearAnimation();

Frame animation:

Frame animation represents the animation effect in the process of view switching. It can be the switching between activities or the switching of views. Switching between activities may be a more common type of frame animation. When we need to destroy or start an activity, follow finish() or startActivity() with the following code:

  overridePendingTransition(enterAnim, exitAnim);

Switching animation between activities can be achieved, for example, if the right-sliding effect is to be achieved:

slide_left_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set 
xmlns:android="http://schemas.android.com/apk/res/android">
<translate
    android:duration="300"
    android:fromXDelta="-100%p"
    android:toXDelta="0">
</translate>
</set>

slide_right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set 
xmlns:android="http://schemas.android.com/apk/res/android">
 <translate
    android:duration="300"
    android:fromXDelta="0"
    android:toXDelta="100%p">
</translate>
</set>

After finish() or startActivity(), add:

 overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);

If we switch between view s, we can use Animation Drawable to achieve, for example:

frame_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@android:color/white" android:duration="500"></item>
<item android:drawable="@android:color/holo_green_dark" android:duration="500"></item>
<item android:drawable="@android:color/black" android:duration="500"></item>
</animation-list>

In activity, the following call is made:

view = findViewById(R.id.activity_main);
view.setBackgroundResource(R.drawable.frame_animation);
view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AnimationDrawable aniDrawable = (AnimationDrawable) view.getBackground();
            aniDrawable.start();
        }
    });

I've just changed the background of view, and of course you can also set the android:drawable property to your favorite image.

Next let's look at the properties animation:

In our application and development, attribute animation is generally the most commonly used type of animation. The main feature of attribute animation is the change of view attribute value, which is different from other animations. Attribute animation is the product of android 3.0 (API 11), which can achieve richer animation effects than traditional animation. If the Android version before 3.0 also wants to use attribute animation, you can use the Nineold androids open source animation library, the website is: http://nineoldandroids.com Attribute animation can be roughly divided into View Animator, Object Animator and Value Animator from simplicity to difficulty in implementation.

Let's first look at ViewAnimator, which is mainly used for its subclass ViewProperty Animator. The use of ViewProperty Animator animation comes from the four transformations of view: translation, zooming, rotation and transparency, which we are familiar with. Namely:

view.setTranslationX(float translationX);
view.setTranslationY(float translationY);
view.setTranslationZ(float translationZ);
    
view.setScaleX(float scaleX);
view.setScaleY(float scaleY);
    
view.setRotation(float rotation);
view.setRotationX(float rotationX);
view.setRotationY(float rotationY);
    
view.setAlpha(float alpha);

It's also easy to use, one line of code can do it:

view.animate().translationX(500);

Animation processing can also be performed based on previous positions:

view.animate().translationYBy(500);

Other animations are similar, so there are no examples. Of course, besides these single animations, there are many kinds of animations that can be carried out at the same time, such as this way of writing:

view.animate()
            .translationX(500)
            .scaleY(4)
            .rotation(360)
            .alpha(0.5f);

Attribute animation can generally set up two types of listeners at the same time:

view.animate().setListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {

        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

Represents the execution cycle callback of the animation.

view.animate().setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {

        }
    });

Indicates that the animation callback in the execution process, each frame (not exactly 10 ms) will be a callback, according to which we can deal with some things in the animation execution process.

Object Animator is more powerful than ViewProperty Animator, but it is also more complex to operate. Object Animator is realized by constantly changing attribute values. Let's first look at how Object Animator achieves animation effects.

For example, we need to constantly change the ProgressBar progress bar to achieve the animation effect, we can write as follows:

ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", 0, 100);
animator.start();

Here are a few points to note:
1. Because programs are ints, we need to use ofInt method to generate Object Animator method, and ofFloat() is the same, but color can not be used in this way, because we know that each Byte has different meanings if it is expressed by argb, but not by simple int value, so android provides us with ofArgb() for color processing. Changeable.

2. The "progress" attribute must exist, and there must be setProgress() and getProgress () that provide good setProgress() and getProgress ().

In addition, we can also use AnimatorSet to make our animations work at the same time, such as:

AnimatorSet aniSet = new AnimatorSet();
aniSet.playTogether(animator1, animator2);

It can also be executed in a certain order:

AnimatorSet aniSet = new AnimatorSet();
aniSet.playSequentially(animator2, animator1);

Property Values Holder can also be used:

PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofFloat("scaleX", 0, 1);
PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofFloat("scaleY", 0, 1);
PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha", 0, 1);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, scaleXHolder, scaleYHolder, alphaHolder);
animator.start();

It can also be different stages of the same animation, i.e. animation completion/animation time:

Keyframe step1 = Keyframe.ofFloat(0, 0);
Keyframe step2 = Keyframe.ofFloat(0.5f, 100);
Keyframe step3 = Keyframe.ofFloat(1, 50);
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("progress", step1, step2, step3);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder);
animator.start();

Of course, in addition to the system to provide us with good properties, we can also define their own properties in the control. It should be used at this time, for example:

ObjectAnimator animator = ObjectAnimator.ofObject(view, "position",
new PointFEvaluator(), new PointF(0, 0), new PointF(1, 1));
animator.setDuration(1000);
animator.start();

Because the position attribute is a coordinate point, that is, a PointF object, the system does not provide us with a specific interface. At this time, we need to implement it by ourselves, through ofObject, and our custom view must have position attribute and setPosition method. Since the ofObject method is implemented, we need to implement our own estimator to implement the TypeEvaluator() interface.

private class PointFEvaluator implements TypeEvaluator<PointF> {

    // Rewrite the evaluation () method so that PointF can be animated as an attribute
    @Override
    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
        PointF outPointF = new PointF();
        outPointF.x = startValue.x + (endValue.x - startValue.x) * fraction;
        outPointF.y = startValue.y + (endValue.y - startValue.y) * fraction;
        return outPointF;
    }
}

Finally, let's take a look at Value Animator. Value Animator is the parent of Object Animator, but Value Animator can't specify the goal of animation. So if we want to use Value Animator to achieve the effect of animation, we can achieve the effect of animation by implementing the Type Evaluator interface and going to invalidate() target view when each frame of animation arrives.

Some of the animations we're going to talk about may be less, but for our engineers, it makes our applications look more dazzling.

The first is Layout Animation. Layout Animation mainly acts on ViewGroup. It is also a view animation, often on ListView or GridView, so that when the child view appears, it has certain dynamic effect.

layout_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="500"
android:animationOrder="normal"
android:animation="@android:anim/fade_in"/>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView 
xmlns:android="http://schemas.android.com/apk/res/android"

...
android:id="@+id/listview"
android:layoutAnimation="@anim/layout_animation"
...
/>

In addition to specifying animation effects in xml, you can specify in your code:

listview = findViewById(R.id.listview);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.layout_animation);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);

Next comes the gif animation, which is to play a gif picture. I also refer to this blog post on the internet, let's not talk about it. Here's a good article for you to see. http://blog.csdn.net/guolin_blog/article/details/11100315

Finally, we will talk about three kinds of 3D animation: rotation, translation, mobile camera. The main purpose of 3D animation is Camera. The principle of 3D animation is to project the view through Camera to achieve 3D effect. Camera uses the 3D coordinate system and still takes the upper left corner as the origin of coordinates (0, 0, 0), which is consistent with Canvas. x is positive and negative on the right, and y is negative on the y. Positive and negative, z family is perpendicular to positive and negative outside the screen. The rotation direction is to rotate positively from the outside to the inside of the screen, clockwise from the y group, and from the right to the left from the z group. Camera's default coordinate position is (0, 0, - 576). We can adjust its position through setLocation.

We use an example to see how to achieve 3D effects:

First you need to customize a 3D animation:

public class Rotate3DAnimation extends Animation {

private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private boolean mReverse;
private Camera mCamera;
private float scale = 2.5f;

/**
 * Create a 3-D animation effect that rotates around the y axis, with depth adjustment during rotation, and can specify the rotation center.
 *
 * @param fromDegrees   Initial Angle
 * @param toDegrees     End Angle
 * @param centerX       x coordinates of the center of rotation
 * @param centerY       y coordinates of the center of rotation
 * @param depthZ        Farthest-reaching z-axis coordinates
 * @param reverse       true Represents the opposite from 0 to depthZ, false
 */
public Rotate3DAnimation(float fromDegrees, float toDegrees,
                         float centerX, float centerY, float depthZ, boolean reverse) {
    mFromDegrees = fromDegrees;
    mToDegrees = toDegrees;
    mCenterX = centerX;
    mCenterY = centerY;
    mDepthZ = depthZ;
    mReverse = reverse;
}

@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    mCamera = new Camera();
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    final float fromDegrees = mFromDegrees;
    float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
    final float centerX = mCenterX;
    final float centerY = mCenterY;
    final Camera camera = mCamera;
    final Matrix matrix = t.getMatrix();
    camera.save();
    mReverse = interpolatedTime < 0.5?true:false;
    // Depth of adjustment
    if (mReverse) {
        camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
    } else {
        camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
    }

    // Rotating around the y-axis
    camera.rotateX(degrees);

    camera.getMatrix(matrix);
    camera.restore();

    // Correct distortion, mainly modify MPERSP_0 and MPERSP_1
    float[] mValues = new float[9];
    matrix.getValues(mValues);              //Get numerical value
    mValues[6] = mValues[6]/scale;          //Numerical correction
    mValues[7] = mValues[7]/scale;          //Numerical correction
    matrix.setValues(mValues);              //Reassign

    // Regulating Center Point
    matrix.preTranslate(-centerX, -centerY);
    matrix.postTranslate(centerX, centerY);
}
}

Call in Activity:

Rotate3DAnimation rotate3D = new Rotate3DAnimation(0, 90, view.getWidth()/2, view.getHeight()/2, 0, false);
rotate3D.setDuration(1000);
rotate3D.setFillAfter(true);
view.startAnimation(rotate3D);

It's important to note that Camera's execution of animation is in reverse order, but we can specify the order of animation by preTranslate or postTranslate, that is, first translating view to the origin, then rotating around x, and finally translating the result of rotation to the original position.

At this point, all the animation related content is over, if there is any problem, I hope to leave a message.

Topics: Android xml Attribute encoding