Android APP complete basic tutorial (11) application resources - Animation

Animation modes are divided into three categories in the android system:

  1. tween(view) animation: make up animation
  2. frame(drawable) animation: frame by frame animation
  3. property animation: property animation

This chapter is read by aligning them separately.

1 Tween Animation

1.1 Tween Animation Foundation

Animation is defined in XML format. The XML file is stored in the path res/anim. Here, we introduce Tween Animation according to the XML document structure {parent node | child node | attribute}. First introduce the common node attributes of Tween Animation, as shown below:

Tween Animation consists of four basic animations: alpha (gradient transparency), scale (scale), translate (position movement), and rotate. At the same time, the Animation class has four sub classes: alpha Animation, ScaleAnimation, TranslateAnimation, and rotateanimation. Each sub class adds its own unique attributes on the basis of the parent class. They are interpreted as follows:

@1 Alpha attribute description:

@2 Scale attribute description:

@3. Description of translate attribute:

@4 description of rotate attribute:

1.2 usage of Tween Animation

There are two uses of Tween Animation: reading from XML files and setting / reading from code.

@1 read Animation directly from XML resources in the code and use

The animation defined in XML is placed in the /res/anim/ folder. The root element of the XML file can be <alpha>, <scale>, <translate>, <rotate>, interpolator element or <set> (represents the collection of the above animations, and set can be nested). By default, all animations are performed at the same time. You can set the start offset (start time) of each animation through the startOffset attribute to achieve the effect of animation sequence playback. After defining the animation XML file, apply the animation to the specified View through code. As follows:

ImageView XXXImage = (ImageView)findViewById(R.id.spaceshipImage);
Animation yyyAnimation=AnimationUtils.loadAnimation(this,R.anim.yyy);
XXXImage.startAnimation(yyyAnimation);

@2 set the Tween Animation attribute through code

The Animation subclass is used in the code to initialize the Animation object. The Animation base class contains a large number of set/getXXX() functions to set / read the properties of Animation. For relevant methods, please refer to the document: Android Animation XML attribute.

For animation related methods, please refer to the following documents: Interpretation of Android Animation method.

1.3 operation control and mode of animation

@1 Interpolator

The progress of animation is controlled by interpolator, which defines the change rate of an animation and is used to control the animation at run time. This enables the basic animation effects (alpha, scale, translate, rotate) to accelerate, decelerate, repeat, etc. Interpolator is a base class that encapsulates the common methods of all interpolators. It has only one method, getInterpolation (float input). This method provides several interpolator subclasses and implements different speed curves, as follows:

Note: for LinearInterpolator, the rate of change is a constant, that is, f(x) = x. Several other subclasses of Interpolator also implement the rate of change according to specific algorithms. You can also define your own Interpolator subclass to achieve physical effects such as parabola and free fall.

@2 animation operation mode

  • Exclusive mode: the main thread of the program enters a loop and continuously refreshes the screen according to the animation instructions until the animation ends.
  • Interrupt mode: a single thread counts the time, sends a notice to the main thread at intervals, and the main thread updates the screen after receiving the notice.

@3 animation implementation principle

  • Transformation records the affine Matrix. Each time the animation is triggered, an operation will be performed on the original Matrix. The Bitmap of View can be multiplied by this Matrix to realize the corresponding operations (rotation, translation, scaling, etc.).
  • Graph transformation is realized by affine matrix. Graphic transformation is the basic knowledge in graphics. In brief, each transformation is a matrix operation. In Android, the Canvas class contains the current matrix. When Canvas When drawbitmap (bmp, x, y, paint) is drawn, Android will first perform matrix operation on bmp, and then display the operation results on Canvas. After that, you just need to constantly modify the Canvas matrix and refresh the screen, and the objects in the View will constantly make graphic transformations, thus forming animation.

2 Frame Animation

Android uses the AnimationDrawable class to define and use Frame Animation. It can be defined in the XML Resource (or stored in the res/anim folder), or it can be defined using the API in AnimationDrawable. Different from Tween Animation, Frame Animation plays the pre prepared images in sequence, and simulates the effect of animation through a series of Drawable displays in turn. The definition method in XML is as follows:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/XXX1" android:duration="200" />
    ...
</animation-list>

Note: you must take <animation list> as the root element, use <item> to represent the pictures to be displayed alternately, and the duration attribute represents the display time of each item. XML files should be placed in /res/drawable/

@2 use example of drawable Animation:

Define a frame by frame animation item, and the configuration is as follows:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
   <item android:drawable="@drawable/XXX1″ android:duration="200″ />
   <item android:drawable="@drawable/XXX2″ android:duration="200″ />
   <item android:drawable="@drawable/XXX3″ android:duration="200″ />
</animation-list>

It contains three frames of animation, in which three pictures in drawable are applied respectively: XXX1, XXX2 and XXX3, and each frame of animation lasts for 200 milliseconds. Then we save the above XML in the res/anim/ folder and name it xxx xml.

Write code to display the animation as follows:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    imageView = (ImageView) findViewById(R.id.imageView);
    imageView.setBackgroundResource(R.drawable.drawable_anim);
    anim = (AnimationDrawable) imageView.getBackground();
}

public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        anim.stop();
        anim.start();
        return true;
    }
    return super.onTouchEvent(event);
}

be careful:

  • Call the setBackgroundResource method of Imageview. If you directly set its src attribute in the XML layout file, the ForceClose problem will occur when the animation is triggered.
  • stop() before start(), otherwise the animation will stop at the last frame after the first animation run, so the animation will only be triggered once.
  • Do not call start in onCreate because AnimationDrawable is not fully associated with Window. If you want to start animation when the interface is displayed, you can call start() in onWindowFoucsChanged().

@3 read the introduction to AnimationDrawable in the Android documentation. The key contents are summarized as follows:

For more information about AnimationDrawable, see the documentation: Detailed interpretation of Android AnimationDrawable

Note: the interpolator attribute is not defined in the XML file of Frame Animation because it has no meaning.

3 Animator

Animator represents an attribute animation, but it is only an abstract class. We usually use its subclasses: AnimatiorSet, ValueAnimator, ObjectAnimator, TimeAnimator. The XML file should be placed in res/animator/.

3.1 how attribute animation works

@1 attribute animation, which changes the actual attributes of an object.

In Tween Animation, it changes the drawing effect of the View, and the properties of the View remain unchanged. For example, no matter how you scale the size of the Button in the conversation, the position and size of the Button's effective click area or the area without animation remain unchanged. In attribute animation, the actual attributes of the object are changed, such as the scaling of the Button, and the position and size attribute values of the Button are changed. And attribute animation can be applied not only to View, but also to any object. Attribute animation only represents the change of a value over a period of time. When the value changes, it is up to us to decide what to do.

@2 in Property Animation, you can apply the following properties to Animation:

3.2 interpretation of common attribute Animation & code use ex amp les

3.2.1 ValueAnimator animation (code implementation mechanism)

The core class of the entire attribute animation mechanism. The operation mechanism of attribute animation is realized by continuously operating the values, and the animation transition between the initial value and the end value is calculated by the ValueAnimator class. Internally, it uses a time cycle mechanism to calculate the animation transition between values. We only need to provide the initial value and end value to ValueAnimator, and tell it how long the animation needs to run. Then ValueAnimator will automatically help us to smoothly transition from the initial value to the end value. In addition, ValueAnimator is also responsible for managing the playback times, playback modes, and setting listeners for animation. It is a very important class. However, the usage of ValueAnimator is not complicated at all. The example (a value can be smoothly transitioned from 0 to 1 for 300 milliseconds) is as follows:

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);  
anim.setDuration(300);  
anim.start();  

3.2.2 ObjectAnimator animation (code implementation mechanism)

Compared with ValueAnimator, ObjectAnimator is more commonly used. ValueAnimator only makes smooth animation transition for values. ObjectAnimator (inherited from ValueAnimator) can directly animate any attribute of any object.

@1 alpha case

A TextView changes from normal to fully transparent and then from fully transparent to normal within 5 seconds. The code is as follows:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
animator.setDuration(5000);  
animator.start();  

@2 rotation case

Rotate the TextView 360 degrees once, change the second parameter in @1 to "rotation", and set the initial and end values of the animation to 0 and 360 respectively. The code is as follows:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  
animator.setDuration(5000);  
animator.start();  

@3 translation cases

Move the TextView out of the screen to the left, and then back. The code is as follows:

float curTranslationX = textview.getTranslationX();  
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX",curTranslationX, -500f, curTranslationX);  
animator.setDuration(5000);  
animator.start(); 

First, the getTranslationX() method of TextView is called to get the position of the translationX of the current TextView. Then the second parameter of ofFloat() method is passed into "translationX". The last three parameters are used to tell TextView how to move.

@4 Scale instance

Enlarge the TextView three times in the vertical direction and restore it. Change the second parameter of the ofFloat() method to "scaleY", which means to zoom in and out in the vertical direction. The code is as follows:

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);  
animator.setDuration(5000);  
animator.start();  

@5 special instructions

As for the second parameter of the ofFloat() method, the transfer parameter is not limited to the values of alpha, rotation, translationX and scaleY. We can pass any value to the second parameter of the ofFloat() method. Because the ObjectAnimator is not designed for the View, but for any object. Its job is to continuously assign a value to an attribute in an object, and then the object decides how to display it according to the change of the attribute value.

3.2.3 combined animation

@1 Basic Concepts

The visual effect of independent animation is limited, so it is particularly important to combine multiple animations to play together. The implementation of composite animation mainly relies on the AnimatorSet class, which provides a play() method. An Animator object (ValueAnimator or ObjectAnimator) passed in will return an AnimatorSet Builder instance, AnimatorSet The builder includes the following four methods:

after(Animator anim)    //Inserts an existing animation after the incoming animation.
after(long delay)       //Delay the execution of an existing animation by a specified number of milliseconds.
before(Animator anim)   //Inserts an existing animation before the incoming animation.
with(Animator anim)     //Executes the existing animation and the incoming animation at the same time.

With these four methods, we can complete the logic of combined animation.

@2 use cases

Here, let the TextView move into the screen from outside the screen, and then rotate it 360 degrees to fade in and out at the same time. The key codes are as follows:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f); 
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
AnimatorSet animSet = new AnimatorSet();  
animSet.play(rotate).with(fadeInOut).after(moveIn);  
animSet.setDuration(5000);  
animSet.start();     

First create three animation objects, then create an AnimatorSet object, and then sort the three animation objects for playback. Let the rotation and fade in and fade out animations go on at the same time, and insert them behind the translation animation. Finally, set the animation duration and start the animation.

3.3 attribute animation XML usage examples

3.3.1 ValueAnimator animation example

In the ValueAnimator code and xml settings, there is no setPropertyName because it is not an operation object. It is only necessary to add a listener to listen to changes in value and handle them accordingly. xm is configured as follows:

<?xml version="1.0" encoding="utf-8"?>  
<animator xmlns:android="http://schemas.android.com/apk/res/android"   
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:duration="10000"  
    android:startOffset="1000"  
    android:repeatCount="infinite"  
    android:repeatMode="restart"  
    android:valueFrom="1"  
    android:valueTo="100"  
    android:valueType="intType">  
</animator>  

Load the XML animation. The key codes are as follows:

ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);  
valueAnimator.setTarget(tv_num);  
valueAnimator.setEvaluator(new TypeEvaluator<Integer>() {  
    @Override   
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {  
        System.out.println("Time ratio, fraction:" + fraction);  
        System.out.println("Result value:" + (int)((startValue + fraction * (endValue - startValue)) / 10 * 10));  
        return (int)((startValue + fraction * (endValue - startValue)) / 10 * 10);  
    }  
});  
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {  
    @Override  
    public void onAnimationUpdate(ValueAnimator animation) {  
        //In onAnimationUpdate, this value returns the evaluate value of the current frame of the first animation
        System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue());  
        tv_num.setText(animation.getAnimatedValue() + "");  
    }  
});  
valueAnimator.start();  

3.3.2 usage examples of objectanimator animation XML

The animation XML is defined as follows:

<?xml version="1.0" encoding="utf-8"?>  
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
    android:duration="2000"  
    android:propertyName="scaleX"  
    android:repeatCount="1"  
    android:repeatMode="reverse"  
    android:valueFrom="1.0"  
    android:valueTo="2.0" >  
</objectAnimator> 

Load the XML animation. The key codes are as follows:

imageview_scale.setBackground(getResources().getDrawable(R.drawable.a11));  
ObjectAnimator scaleAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.scale_object_animator);  
scaleAnimator.setTarget(imageview_scale);//Animate the target object
scaleAnimator.setDuration(1000);  
scaleAnimator.setRepeatCount(50);  
scaleAnimator.start();  

3.3.3 AnimatorSet animation set

It is composed of ObjectAnimator and ValueAnimator. The corresponding xml is written similarly as

<set> <objectAnimator /> ... <animator />... </set>

The animation set defined by XML is usually under the folder res/animator. Here is res/animator/set_rotate_scale.xml

@1. The XML configuration file is defined as follows:

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android"   
    android:ordering="together">
    <!-- android:ordering  together Indicates that the animation is running at the same time,  sequentially Indicates that the following animation is executed in sequence -->  
    <set>  
        <objectAnimator  
            android:propertyName="rotationX"  
            android:repeatCount="50"  
            android:repeatMode="reverse"  
            android:valueFrom="0"  
            android:valueTo="20" />  
        <objectAnimator  
            android:propertyName="rotationY"  
            android:repeatCount="50"  
            android:repeatMode="reverse"  
            android:valueFrom="0"  
            android:valueTo="45"  
            android:valueType="floatType" />  
    </set>  
    <set>  
        <objectAnimator  
            android:propertyName="scaleX"  
            android:repeatCount="50"  
            android:repeatMode="reverse"  
            android:valueFrom="1.0"  
            android:valueTo="2.0" >  
        </objectAnimator>  
        <objectAnimator  
            android:propertyName="scaleY"  
            android:repeatCount="50"  
            android:repeatMode="reverse"  
                android:valueFrom="1.0"  
                android:valueTo="2.0" >  
            </objectAnimator>  
    </set>
</set>

Load the XML animation set, and the code implementation is as follows:

imageview_rotate.setBackground(getResources().getDrawable(R.drawable.a11));  
AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set_rotate_scale);  
animatorSet.setTarget(imageview_rotate);  
animatorSet.setDuration(1000);  
animatorSet.setInterpolator(new BounceInterpolator());//Bounce inserter when end is set
animatorSet.start();

For more information on animation, see the documentation: Android animation interpretation

4 Animator listener

If we want to listen to animation events, when the animation starts and ends, and then perform some logic processing at the beginning or end. This function can be fully implemented. The Animator class provides an addListener() method, which receives an AnimatorListener. We only need to implement this AnimatorListener to listen to various events of animation.

As long as it inherits from Animator, addListener() is a general method. The code for adding a listener is as follows:

anim.addListener(new AnimatorListener() {  
    @Override  
    public void onAnimationStart(Animator animation) {/*At the beginning of the animation*/}  
  
    @Override  
    public void onAnimationRepeat(Animator animation) {/*When animation repeats*/}  
  
    @Override  
    public void onAnimationEnd(Animator animation) {/*At the end of the animation*/}  
  
    @Override  
    public void onAnimationCancel(Animator animation) {/*When animation is canceled*/}  
});  

However, sometimes I just want to listen to a single event of animation response, so I can use AnimatorListenerAdapter. This class can solve the problem of cumbersome interface implementation, as shown below:

anim.addListener(new AnimatorListenerAdapter() {});  

Here, we pass this adapter object to the addListener() method. Since each interface has been implemented in the AnimatorListenerAdapter, there is no need to implement any method and no error will be reported. If you want to listen to the end of animation, you only need to rewrite this method separately, as shown below:
 

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

Tags: Android css3 animation app

Posted by techker on Thu, 02 Jun 2022 01:39:46 +0530