Android Advanced - Animation Mechanism and Use

**

1. Android View animation framework

**
The Animation framework defines several common animations of transparency, rotation, scaling and displacement, and controls the entire View. The implementation principle is that the drawChild function in the ViewGroup where the View is located each time the View is drawn. Get the Transformation value of the View's Animaion , and then call canvas.concat(transformToApply.getMatrix()) to complete the animation frame through matrix operations. If the animation is not completed, continue to call the invalidate() function, start the next drawing to drive the animation, and complete the drawing of the entire animation.

1.1 Transparent animation

 AlphaAnimation aa = new AlphaAnimation(0, 1);
        aa.setDuration(1000);
        as.addAnimation(aa);

1.2 Rotation animation

//设置旋转参数以自身中心点
RotateAnimation ra = new RotateAnimation(0, 360,
                RotateAnimation.RELATIVE_TO_SELF, 0.5F,
                RotateAnimation.RELATIVE_TO_SELF, 0.5F);
        ra.setDuration(1000);
        view.startAnimation(ra);

1.3 Displacement animation

//设置以自身中心点
 TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 300);
        ta.setDuration(1000);
        view.startAnimation(ta);

1.4 Zoom animation

 ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1,
                Animation.RELATIVE_TO_SELF, 0.5F,
                Animation.RELATIVE_TO_SELF, 0.5F);
        sa.setDuration(1000);
        view.startAnimation(sa);

1.5 Animation Collection

 AnimationSet as = new AnimationSet(true);
        as.setDuration(1000);

        AlphaAnimation aa = new AlphaAnimation(0, 1);
        aa.setDuration(1000);
        as.addAnimation(aa);

        TranslateAnimation ta = new TranslateAnimation(0, 100, 0, 200);
        ta.setDuration(1000);
        as.addAnimation(ta);

        view.startAnimation(as);

For animation time, Android also provides corresponding monitoring callbacks, and corresponding monitoring methods must be added.

 AlphaAnimation aa = new AlphaAnimation(0, 1);
        aa.setDuration(1000);
        view.startAnimation(aa);
        aa.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

Through this listener callback, you can get the start, end and repeat events of the animation, and do different processing for the relative events.

2. Android attribute animation analysis

The emergence of attribute animation is because the animation framework Animation before Android 3.0 has limitations, changing the display and not responding to events.
2.1 ObjectAnimator
ObjectAnimator directly returns an ObjectAnimator object through its static factory class.
example:

ObjectAnimator animator = ObjectAnimator.ofFloat(
                view,
                "translationX",
                300);
        animator.setDuration(300);
        animator.start();

The first parameter is the View to be manipulated, the second parameter is the property to be manipulated, and the last parameter is a variable array parameter.
When using ObjectAnimator, the properties to be manipulated must have get and set methods, otherwise ObjectAnimator will not work. The following are commonly used property values ​​that can be directly used for property animation.
1.translationX and translationY: These two properties are used as an increment to control the offset position of the View object from the upper left corner of its layout container.
2.roation, ratioX and rationalY: These three properties control the View object around the pivot Perform 2D and 3D rotations.
3.scaleX and scaleY: These two properties control the 2D scaling of the View object around the pivot
4. pivotX and pivotY: Rotate and scale transformation around the pivot. The default pivot position is the center of the View object.
5.x and y: Describe the final position of the View object in its container, which is the cumulative sum of the initial upper-left corner coordinates and the translationX and translationY values.
6.alphabet: It represents the alpha transparency of the View object. The default value is 1 (opaque), 0 is transparent

2.2 PropertyValuesHolder
is similar to AnimationSet and acts on multiple animations at the same time.
example:

PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofFloat("translationX",300);
        PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("ScaleX",1.0f,0.2f,1.0f);
        ObjectAnimator.ofPropertyValuesHolder(view,propertyValuesHolder,propertyValuesHolder1).setDuration(300).start();

2.3 ValueAnimator
ValueAnimator itself does not provide an animation process, allowing the caller to control the animation implementation process.
Usually, the change of the value is monitored in the AnimatorUpdateListener of ValueAnimator to complete the animation change.

final ValueAnimator animator1 = ValueAnimator.ofFloat(0,100);
        animator1.setTarget(view);
        animator1.setDuration(1000).start();
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value  = (Float) animator1.getAnimatedValue();
            }
        });

2.4 Monitoring
of animation events A complete animation has four processes: Start, Repeat, End, and Cancel.

ObjectAnimator anim = ObjectAnimator.ofFloat(view,"alpha",0.5f);
        anim.addListener(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) {

            }
        });   
        anim.start();

Most of the time, we only care about the onAnimationEnd event, so Android also provides an AnimationListenerAdapter to let us choose the necessary events to listen to

anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });

2.6 AnImatorSet has
multiple property animation effects. The advantage of AnimatorSet over PropertyValuesHolder is to achieve more precise sequence control.

  ObjectAnimator propertyValuesHolder = ObjectAnimator.ofFloat(view,"translationX",300);
        ObjectAnimator propertyValuesHolder1 = ObjectAnimator.ofFloat(view,"ScaleX",1.0f,0.2f,1.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        set.playTogether(propertyValuesHolder,propertyValuesHolder1);
        set.start();

In property animation, AnimatorSet controls how multiple animations work together through playTogether(), playSequentially(), animSet.play(), with(), before(), after().

2.6 Using attribute animation in XML
Attribute animation, like view animation, can also be written directly in XML file, the code is as follows

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:interpolator="@android:interpolator/accelerate_decelerate"
    android:propertyName="trimPathStart"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType" />

Programmatically use XML-defined property animations

public void scaleX(View view){
        Animator animator = AnimatorInflater.loadAnimator(this,R.animator.scalex);
        animator.setTarget(mMv);
        animator.start();
    }

2.7 View's animate method
can be considered as a shorthand for attribute animation

 imageView.animate().alpha(0).y(300).setDuration(300).withStartAction(new Runnable() {
            @Override
            public void run() {

            }
        }).withEndAction(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

**

3. Android layout animation

**
The so-called layout animation refers to acting on the ViewGroup, adding an animation excessive effect when adding a View to the ViewGroup.
The simplest layout animation is to use the following code to turn on the layout animation in the XML of the ViewGroup.

android:animateLayoutChanges="true"

With the above code settings, when a View is added to the ViewGroup, the sub-View will show an excessive effect that is gradually displayed. This is the default effect, and this effect cannot be replaced with a custom animation.
In addition, you can also define the transition effect of a child View by using the LayoutAnimationController class, the code is as follows

LinearLayout ll = (LinearLayout)findViewById(R,id.ll);
        //设置过度动画
        ScaleAnimation sa = new ScaleAnimation(0,1,0,1);
        sa.setDuration(2000);
        //设置动画的显示属性
        LayoutAnimationController lac = new LayoutAnimationController(sa,0.5F);
        lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
        //为ViewGroup设置布局动画
        ll.setLayoutAnimation(lac);

This is the first parameter of LayoutAnimationController to set a zooming animation effect for the child View
, which is the animation that needs to be applied, and the second parameter is the delay time displayed by the umeige child View. When the delay time is not 0. The order in which child Views are displayed can be set as follows:

lac.setOrder(LayoutAnimationController.ORDER_NORMAL);//顺序
        lac.setOrder(LayoutAnimationController.ORDER_RANDOM);//随机
        lac.setOrder(LayoutAnimationController.ORDER_REVERSE);//反序
  ```
  **Interpolator(插值器)**
  主要作用是控制目标变量的变化值进行对应的变化。

4. Custom Animation

To create a custom animation, you only need to implement its applyTransformation logic, but usually, you need to override the iniaialize method of the parent class to implement some initialization work. The applyTransformation method has two parameters as shown below.

 applyTransformation(
            float interpolatedTime,
            Transformation t)

The first parameter, interpolatedTime, is the time factor of the interpolator. This factor is calculated by the current completion percentage of the animation and the interpolator corresponding to the current time
. It is the encapsulation class of rectangle. Generally, this class is used to obtain the current rectangle object. The code is as follows

final Matrix matrix = t.getMatrix();

By changing the obtained matrix object, the animation effect can be realized, and for the transformation operation of the matrix, basically any effect animation can be realized.

 @Override
    protected void applyTransformation(
            float interpolatedTime,
            Transformation t) {
        final Matrix matrix = t.getMatrix();
        matrix.preScale(1,
                1 - interpolatedTime,
                mCenterWidth,
                mCenterHeight);
    }

The specific matrix processing method:

        final Matrix matrix = t.getMatrix();
        matrix.preScale(1,
                1 - interpolatedTime,
                mCenterWidth,
                mCenterHeight);
    }

Among them, mCenterWidth and mCenterHeight are the center point of the zoom, which is set as the center of the picture.
An animation that simulates the TV turning off:

public class CustomTV extends Animation {

    private int mCenterWidth;
    private int mCenterHeight;
    private Camera mCamera = new Camera();
    private float mRotateY = 0.0f;

    @Override
    public void initialize(int width,
                           int height,
                           int parentWidth,
                           int parentHeight) {

        super.initialize(width, height, parentWidth, parentHeight);
        // 设置默认时长
        setDuration(1000);
        // 动画结束后保留状态
        setFillAfter(true);
        // 设置默认插值器
        setInterpolator(new AccelerateInterpolator());
        mCenterWidth = width / 2;
        mCenterHeight = height / 2;
    }

    // 暴露接口-设置旋转角度
    public void setRotateY(float rorateY) {
        mRotateY = rorateY;
    }

    @Override
    protected void applyTransformation(
            float interpolatedTime,
            Transformation t) {
        final Matrix matrix = t.getMatrix();
        matrix.preScale(1,
                1 - interpolatedTime,
                mCenterWidth,
                mCenterHeight);
    }
}
 public void imgClose(View view) {
        CustomTV customTV = new CustomTV();
        view.startAnimation(customTV);
    }

In fact, you can set a more accurate interpolator and split the time factor from 0 to 1.0 into different processes, so that different animation effects can be used for different processes to simulate more realistic special effects.

public class CustomAnim extends Animation {

    private int mCenterWidth;
    private int mCenterHeight;
    private Camera mCamera = new Camera();
    private float mRotateY = 0.0f;

    @Override
    public void initialize(int width,
                           int height,
                           int parentWidth,
                           int parentHeight) {

        super.initialize(width, height, parentWidth, parentHeight);
        // 设置默认时长
        setDuration(2000);
        // 动画结束后保留状态
        setFillAfter(true);
        // 设置默认插值器
        setInterpolator(new BounceInterpolator());
        mCenterWidth = width / 2;
        mCenterHeight = height / 2;
    }

    // 暴露接口-设置旋转角度
    public void setRotateY(float rotateY) {
        mRotateY = rotateY;
    }

    @Override
    protected void applyTransformation(
            float interpolatedTime,
            Transformation t) {
        final Matrix matrix = t.getMatrix();
        mCamera.save();
        // 使用Camera设置旋转的角度
        mCamera.rotateY(mRotateY * interpolatedTime);
        // 将旋转变换作用到matrix上
        mCamera.getMatrix(matrix);
        mCamera.restore();
        // 通过pre方法设置矩阵作用前的偏移量来改变旋转中心
        matrix.preTranslate(mCenterWidth, mCenterHeight);
        matrix.postTranslate(-mCenterWidth, -mCenterHeight);
    }
}
  public void btnAnim(View view) {
        CustomAnim customAnim = new CustomAnim();
        customAnim.setRotateY(30);
        view.startAnimation(customAnim);
    }

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325721833&siteId=291194637