Android Property Animation is completely parsed (on) and androidproperty

Source: Internet
Author: User

Android Property Animation is completely parsed (on) and androidproperty

Reprinted please indicate the source:

1. Overview

Android provides several Animation types: View Animation, Drawable Animation, and Property Animation. View Animation is quite simple, but it only supports simple scaling, translation, rotation, and transparency animations, and has certain limitations. For example, you want the View to have a color switching animation; you want to use a 3D Rotation animation; you want the View position to be the current position when the animation is stopped; none of these views can be implemented. This is why Property Animation is generated. This blog introduces the usage of Property Animation in detail. For Drawable Animation, well, slightly ~

2. Related APIs

Property Animation: the attribute of an object is changed through Animation. First, we need to understand several attributes:

Duration animation Duration. The default value is 300 ms.

Time interpolation: Time difference. At first glance, I don't know what it is, but I am talking about LinearInterpolator, AccelerateDecelerateInterpolator. You must know what it is, and define the animation change rate.

Repeat count and behavior: Repeat count and behavior. You can define the number of Repeat times.

Animation sets: an animation set. You can define an animation group to be executed together or sequentially.

Frame refresh delay: Specifies the Frame refresh delay. The default value is 10 ms, but it depends on the current state of the system.

Related Classes

ObjectAnimator animation execution class, which will be detailed later

ValueAnimator animation execution class, which will be detailed later

AnimatorSet is used to control the execution of a group of animations: linear, together, and successively executed by each animation.

AnimatorInflater: xml file for loading property Animation

The TypeEvaluator type value is mainly used to set the animation operation attribute value.

TimeInterpolator time interpolation, as described above.

In general, attribute animation is an animation execution class that sets the attributes, duration, start and end attribute values, and time difference of the animation operation object, then, the system dynamically changes the attributes of the Object Based on the set parameters.

3. ObjectAnimator Animation

Select ObjectAnimator as the first ~~ This is because this implementation is the simplest ~~ One line of code is used to implement animation in seconds. The following is an example:
Layout file:

<RelativeLayout xmlns:android=""    xmlns:tools=""    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/id_container" >    <ImageView        android:id="@+id/id_ball"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:src="@drawable/mv"         android:scaleType="centerCrop"        android:onClick="rotateyAnimRun"        /></RelativeLayout>

It's easy, just a girl picture ~
Activity Code:

package com.example.zhy_property_animation;import android.animation.ObjectAnimator;import;import android.os.Bundle;import android.view.View;public class ObjectAnimActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.xml_for_anim);}public void rotateyAnimRun(View view){ ObjectAnimator// .ofFloat(view, "rotationX", 0.0F, 360.0F)// .setDuration(500)// .start();}}


Is it possible to implement simple animation with a line of code ~~

For ObjectAnimator

1. ofInt, ofFloat, and ofObject are provided. These methods are used to set the elements, attributes, start and end of the animation, and any attribute values in the middle of the animation.

When only one attribute value is set, it is considered that the value of this attribute of the object is the start (obtained by getPropName reflection), and the set value is the end point. If two values are set, the first value is the end value and the other value is the end value ~~~

During the animation update process, attributes of the setPropName update element are constantly called. All attributes updated using ObjectAnimator must have the getter (when setting an attribute value) and setter Methods ~

2. If you operate on this attribute method of the object, for example, setRotationX in the above example, if you do not call repainting of view internally, You need to manually call it as follows.

anim.addUpdateListener(new AnimatorUpdateListener(){@Overridepublic void onAnimationUpdate(ValueAnimator animation){//view.postInvalidate();//view.invalidate();}});
3. After reading the example above, because only one attribute is set for the operation, if I want an animation to make the View zoom out and fade out, scaleY, alpha), only use ObjectAnimator. What should I do?

The idea is not very good. It may be said that the use of AnimatorSet is a bunch of animation plug-ins for execution, but I have to use an ObjectAnimator instance for implementation ~ See the code below:

public void rotateyAnimRun(final View view){ObjectAnimator anim = ObjectAnimator//.ofFloat(view, "zhy", 1.0F,  0.0F)//.setDuration(500);//anim.start();anim.addUpdateListener(new AnimatorUpdateListener(){@Overridepublic void onAnimationUpdate(ValueAnimator animation){float cVal = (Float) animation.getAnimatedValue();view.setAlpha(cVal);view.setScaleX(cVal);view.setScaleY(cVal);}});}

Write the character string that sets the attribute to an attribute that is not available to the object ~~ We only need the value calculated by time interpolation and duration, and we manually call it ~


In this example, I want to explain that sometimes I don't want to be restricted by the API, and some functions provided by the API can also achieve interesting results ~~~

For example, if you want to achieve the parabolic effect, 100px/s in the horizontal direction, and 200px/s * s in the vertical direction, how can this be achieved ~~ You can try it with ObjectAnimator ~

4. There is actually a simpler way to change multiple effects of an animation: Using propertyValuesHolder

public void propertyValuesHolder(View view){PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,0f, 1f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,0, 1f);PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,0, 1f);ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();}

4. ValueAnimator Animation

Similar to ObjectAnimator, you can simply look at the animation code for vertical movement of a view:

public void verticalRun(View view){ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight- mBlueBall.getHeight());animator.setTarget(mBlueBall);animator.setDuration(1000).start();}

Does it make you feel like it is? It's different from ValueAnimator ~ However, you can see that no operation attribute is set ~~ That is to say, the above Code has no effect and no attribute is specified ~

This is the difference between ValueAnimator and ValueAnimator: ValueAnimator does not perform operations on attributes. What are the advantages of ValueAnimator? Don't I have to set it manually?

Benefit: the attributes of objects that do not need to be operated must have the getter and setter methods. You can operate any attribute based on the calculated value of the current animation, remember the one in the above example [I want an animation to make the View zoom out and fade out (three attributes: scaleX, scaleY, and alpha? This is actually the usage ~


Layout file:

<RelativeLayout xmlns: android = "" xmlns: tools = "" android: layout_width = "match_parent" android: layout_height = "match_parent" android: id = "@ + id/id_container"> <ImageView android: id = "@ + id/id_ball" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: src = "@ drawable/bol_blue"/> <LinearLayout android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_alignParentBottom = "true" android: orientation = "horizontal"> <Button android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: onClick = "verticalRun" android: text = "vertical"/> <Button android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: onClick = "paowuxian" android: text = "parabolic"/> </LinearLayout> </RelativeLayout>
There is a small ball in the upper left corner and two buttons at the bottom ~ Let's first look at a free-body code:

/*** @ ** @ Param view */public void verticalRun (View view) {ValueAnimator animator = ValueAnimator. ofFloat (0, mScreenHeight-mBlueBall. getHeight (); animator. setTarget (mBlueBall); animator. setDuration (1000 ). start (); // animator. setInterpolator (value) animator. addUpdateListener (new AnimatorUpdateListener () {@ Overridepublic void onAnimationUpdate (ValueAnimator animation) {mBlueBall. setTranslationY (Float) animation. getAnimatedValue ());}});}

Unlike ObjectAnimator, we set the update of element attributes ~ Although several lines of code are added, it seems to improve flexibility ~

Next, let's take another example. If I want a small ball to perform parabolic motion [to achieve the parabolic effect, 100px/s in the horizontal direction, and 200px/s in the vertical direction], let's analyze it, it seems to be related only to time, but the horizontal and vertical moving rates vary according to time changes. How can we achieve this? At this point, it is time to rewrite TypeValue, because we need to return two values to the object, the current position of x, and the current position of y, when time changes:


/*** Parabolic * @ param view */public void paowuxian (View view) {ValueAnimator valueAnimator = new ValueAnimator (); valueAnimator. setDuration (3000); valueAnimator. setObjectValues (new PointF (0, 0); valueAnimator. setInterpolator (new LinearInterpolator (); valueAnimator. setEvaluator (new TypeEvaluator <PointF> () {// fraction = t/duration @ Overridepublic PointF evaluate (float fraction, PointF startValue, PointF endValue) {Log. e (TAG, fraction * 3 + ""); // 0.5 Px/s in the x direction, * 10 * tPointF point = new PointF (); point. x = 200 * fraction * 3; point. y = 0.5f * 200 * (fraction * 3) * (fraction * 3); return point ;}}); valueAnimator. start (); valueAnimator. addUpdateListener (new AnimatorUpdateListener () {@ Overridepublic void onAnimationUpdate (ValueAnimator animation) {PointF point = (PointF) animation. getAnimatedValue (); mBlueBall. setX (point. x); mBlueBall. setY (point. y );}});}
We can see that, because ofInt, ofFloat, and so on cannot be used, we customize a TypeValue and return a PointF object each time based on the current time. (the difference between PointF and Point is x, the unit of y is float and int. RectF and Rect are also) PointF contains the current position of x and y ~ Then we get it in the listener and dynamically set the attributes:


There is a feeling that two iron balls are landing at the same time ~~ Yes. I should have two balls ~~ Ps: if the physical formula is wrong, you will not see it.

Custom generic input by TypeEvaluator can design a Bean as needed.

Now, we have explained the differences between ValueAnimator and ObjectAnimator for implementing animation. How to Use Some APIs to update attributes and customize TypeEvaluator to meet our needs; but we didn't talk about how to design interpolation. In fact, I think the default implementation class of this interpolation is enough ~~ Very few, will design a super abnormal ~ Hmm ~ So: omitted.

5. Listen to animation events

For animations, they are generally secondary effects. For example, if I want to delete an element, I may want to fade out the effect, but I still want to delete it, not because you have no transparency, it still occupies the position, so we need to know how the animation ends.

So we can add an animation listener:

public void fadeOut(View view){ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);anim.addListener(new AnimatorListener(){@Overridepublic void onAnimationStart(Animator animation){Log.e(TAG, "onAnimationStart");}@Overridepublic void onAnimationRepeat(Animator animation){// TODO Auto-generated method stubLog.e(TAG, "onAnimationRepeat");}@Overridepublic void onAnimationEnd(Animator animation){Log.e(TAG, "onAnimationEnd");ViewGroup parent = (ViewGroup) mBlueBall.getParent();if (parent != null)parent.removeView(mBlueBall);}@Overridepublic void onAnimationCancel(Animator animation){// TODO Auto-generated method stubLog.e(TAG, "onAnimationCancel");}});anim.start();}

In this way, you can listen to events such as the start, end, cancellation, and repetition of an animation ~ However, sometimes I feel that I only need to know the end, so long code I cannot receive, then you can use the AnimatorListenerAdapter

anim.addListener(new AnimatorListenerAdapter(){@Overridepublic void onAnimationEnd(Animator animation){Log.e(TAG, "onAnimationEnd");ViewGroup parent = (ViewGroup) mBlueBall.getParent();if (parent != null)parent.removeView(mBlueBall);}});

AnimatorListenerAdapter inherits the AnimatorListener interface, and then empty implements all the methods ~


The animator and cancel () and end () Methods: The cancel animation stops immediately and stops at the current position. The end animation goes directly to the final state.

6. Use of AnimatorSet


Layout file:

<RelativeLayout xmlns: android = "" xmlns: tools = "" android: layout_width = "match_parent" android: layout_height = "match_parent" android: id = "@ + id/id_container"> <ImageView android: id = "@ + id/id_ball" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_centerInParent = "true" android: src = "@ drawable/bol_blue"/> <LinearLayout android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_alignParentBottom = "true" android: orientation = "horizontal"> <Button android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: onClick = "togetherRun" android: text = "simple multi-animation Together"/> <Button android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: onClick = "playWithAfter" android: text = "Multi-animation execution in sequence"/> </LinearLayout> </RelativeLayout>

Continue playing the ball ~


Package com. example. zhy_property_animation; import android. animation. animatorSet; import android. animation. objectAnimator; import android. app. activity; import android. OS. bundle; import android. view. view; import android. view. animation. linearInterpolator; import android. widget. imageView; public class AnimatorSetActivity extends Activity {private ImageView mBlueBall; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. anim_set); mBlueBall = (ImageView) findViewById (R. id. id_ball);} public void togetherRun (View view) {ObjectAnimator anim1 = ObjectAnimator. ofFloat (mBlueBall, "scaleX", 1.0f, 2f); ObjectAnimator anim2 = ObjectAnimator. ofFloat (mBlueBall, "scaleY", 1.0f, 2f); AnimatorSet animSet = new AnimatorSet (); animSet. setDuration (2000); animSet. setInterpolator (new LinearInterpolator (); // The animSet is executed for both animations. playTogether (anim1, anim2); animSet. start ();} public void playWithAfter (View view) {float cx = mBlueBall. getX (); ObjectAnimator anim1 = ObjectAnimator. ofFloat (mBlueBall, "scaleX", 1.0f, 2f); ObjectAnimator anim2 = ObjectAnimator. ofFloat (mBlueBall, "scaleY", 1.0f, 2f); ObjectAnimator anim3 = ObjectAnimator. ofFloat (mBlueBall, "x", cx, 0f); ObjectAnimator anim4 = ObjectAnimator. ofFloat (mBlueBall, "x", cx);/*** anim1, anim2, anim3 simultaneously execute * anim4 and then execute */AnimatorSet animSet = new AnimatorSet (); animSet. play (anim1 ). with (anim2); animSet. play (anim2 ). with (anim3); animSet. play (anim4 ). after (anim3); animSet. setDuration (1000); animSet. start ();}}

Two effects are written:

First, use playTogether to execute the animation at the same time, and playSequentially to execute the animation in sequence ~~

Second, if we have a bunch of animations, how can we use code to control the sequence, such as 1, 2, 3, 2, 4, and so on ~ It's Effect 2.

Note: animSet. play (). with (); also supports chain programming, but do not think crazy, such as animSet. play (anim1 ). with (anim2 ). before (anim3 ). before (anim5); this is not the case. The system won't decide the sequence based on the long string you wrote. So please write several more lines according to the example above:


Okay. Due to the length ~~ You also have some knowledge about property Animation:

1. Create an attribute animation for an xml file

2. layout Animation

3. View animate method.

So I want to write it to the next article, but this is the core function ~~

By the way, if you use sdks earlier than 11, import the nineoldandroids animation library. The usage is basically the same ~

Download source code

What should I do if I want to see an animation in an android program?

In the Android FrameWork, three Animation implementation methods are provided: Frame-by-Frame Animation, View Animation, and Property Animation ).

Based on the descriptions in the SDK, these three functions are powerful: frame-by-frame <view animation <attribute animation.
I. frame-by-frame animation:
This animation collects all the static images in the animation process, displays these images in sequence, and uses the principle of "visual stay" of the human eye, animation effects for users.

Ii. view animation:
It is also called a Tween animation. According to these two definitions, we can see some features of the animation method:
1) The animation method is only for View objects, such as ImageView and Button;
2) To implement this animation, you only need to provide the relevant attributes of two key frames. Android will give you an animation gradient process for two key frames within a specified period of time.

3. Property Animation:
Android introduces property animation in 3.0. Different from view animation's focus and view effect, view animation focuses more on Object attribute changes and implements animation by changing object attributes, regardless of whether the object is visible or not. For example, if you use a view animation to double a Button, the effect on the interface can be achieved, but the touch response area of the Button is the same as the original one, that is, view animation does not actually double the Button.

Android: animation Problems

You can use property animation to adjust translationX or translationY to move the file.

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.