Document directory
- 1. View Animation (Tween Animation)
- 2. Drawable Animation (Frame Animation)
- 3. Property Animation
- 3.1 How Property Animation works
- 3.2 ValueAnimator
- 3.3 ObjectAnimator
- 3.4 apply multiple animations through AnimationSet
- 3.5 TypeEvalutors
- 3.6 TimeInterplator
- 3.7 apply an animation when Layout changes
- 3.8 Keyframes
- 3.9 Animating Views
- 3.10 ViewPropertyAnimator
Android 3.0 and later versions support two animation modes: tween animation and frame animation. In android3.0, a new animation system is introduced: property animation, these three animation modes are called property animation, view animation, and drawable animation in the SDK.
1. View Animation (Tween Animation)
View Animation.
View animation can only be applied to View objects, and only some attributes are supported. For example, it supports scaling and rotation, but does not support background color changes.
In addition, for View animation, it only changes the position of the View object, but does not change the View object itself. For example, you have a Button, coordinate (100,100), Width: 200, Height: 50, and you have an animation to change it to Width: 100, Height: 100, you will find that the area where the trigger button is clicked during the animation is still (100,100)-(300,150 ).
View Animation is a series of View shape transformations, such as scaling the size, changing the transparency, and changing the position. The Animation definition can be defined by code or XML. Of course, we recommend that you use XML.
You can set multiple animations for a View at the same time, such as the fade-in effect from transparency to opacity, And the zoom-in effect from small to large. These animations can be performed simultaneously, you can also start another one after it is complete.
Place the animation defined in XML in the/res/anim/folder. The root element of the XML file can be <alpha>, <scale>, <translate>, <rotate>, the interpolator element or <set> (indicating the set of the above animations. set can be nested ). By default, all animations are simultaneously played. You can use the startOffset attribute to set the start offset (start time) of each animation to play the animation in sequence.
You can change the animation gradient mode by setting the interpolator attribute, such as AccelerateInterpolator. It starts slowly and then gradually speeds up. The default value is AccelerateDecelerateInterpolator.
After the XML file of the animation is defined, you can apply the animation to the specified View using code similar to the following.
ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation=AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);spaceshipImage.startAnimation(hyperspaceJumpAnimation);
2. Drawable Animation (Frame Animation)
Drawable Animation (Frame Animation): A Frame Animation, like a GIF image, is displayed in sequence through a series of Drawable to simulate the Animation effect. The definition in XML is as follows:
1 |
< animation-list xmlns:android = "http://schemas.android.com/apk/res/android" |
2 |
android:oneshot = "true" > |
3 |
< item android:drawable = "@drawable/rocket_thrust1" android:duration = "200" /> |
5 |
< item android:drawable = "@drawable/rocket_thrust2" android:duration = "200" /> |
6 |
< item android:drawable = "@drawable/rocket_thrust3" android:duration = "200" /> |
You must use <animation-list> as the root element and <item> as the image to be rotated. The duration Attribute indicates the display time of each item. The XML file must be stored in the/res/drawable/directory. Example:
protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageView1); 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); }
I encountered two problems in my experiment:
- To call the setBackgroundResource method of Imageview in the Code, if you directly set the src attribute in the XML layout file, FC is triggered when the animation is triggered.
- Stop () before the animation start (). Otherwise, the animation stops at the last frame after the first animation, so that the animation will be triggered only once.
- The last point is mentioned in the SDK. Do not call start in onCreate, because AnimationDrawable is not completely associated with Window. If you want to start animation when the interface is displayed, you can go to onWindowFoucsChanged () start ().
3. Property Animation
Attribute Animation, which was introduced in Android 3.0. The Animation mechanism in the previous study of WPF seems to be this. It changes the actual attributes of the object, in View Animation (Tween Animation) in the dialog box, the rendering effect of the View is changed, and the attributes of the View remain unchanged. For example, no matter how you scale the Button in the dialog box, the effective click area of the Button is still not used when the animation is applied, and its position and size remain unchanged. In Property Animation, the actual attributes of the object are changed, for example, the scaling of the Button, the position and size of the Button, and the attribute values are changed. In addition, Property Animation can be applied not only to View, but also to any object. Property Animation only indicates a change in value within a period of time. When the value changes, you decide what to do.
In Property Animation, you can apply the following attributes to an Animation:
- Duration: animation Duration
- TimeInterpolation: Calculation of attribute values, such as fast and slow
- TypeEvaluator: calculates the attribute value of the current time based on the start, end, And TimeInterpolation of the attribute.
- Repeat Country and behavoir: Repeat times and modes, such as three, five, and infinite loop playback. You can Repeat the animation all the time, or play it back after playback.
- Animation sets: an Animation set. You can apply several animations to an object at the same time. These animations can be played at the same time or different start offsets can be set for different animations.
- Frame refreash delay: the refresh time, that is, the number of times the attribute value is calculated. The default value is 10 ms. The final refresh time is also affected by system process scheduling and hardware.
3.1 How Property Animation works
For the animation, the X coordinate of this object is moved from 0 to 40 pixel within 40 ms. Refresh the object once every 10 ms by default. this object will be moved four times, and each time it is moved 40/4 = 10 pixel.
You can also change the method of changing the attribute value, that is, set different interpolation to gradually increase or decrease the speed of medium motion.
Displays key objects related to the preceding animation.
ValueAnimator indicates an animation, which includes attributes such as the animation start value, end value, and duration.
ValueAnimator encapsulates a TimeInterpolator, which defines the interpolation method between the attribute value and the end value.
ValueAnimator also encapsulates a TypeAnimator and calculates the attribute value based on the value calculated from the start, end, And TimeIniterpolator.
ValueAnimator calculates a time factor (0 ~ 1), and then calculate another factor based on TimeInterpolator. Finally, TypeAnimator calculates the attribute value through this factor. In the above example, 10 MS:
Calculate the time factor, that is, the percentage of time elapsed: t = 10 ms/40 ms = 0.25
The interpolation factor after interpolation (inteplator) is about 0.15. In the preceding example, AccelerateDecelerateInterpolator is used. The formula is (input is the time factor ):
(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
Finally, the attribute value for 10 ms is calculated based on the TypeEvaluator: 0.15 * (40-0) = 6 pixel. In the preceding example, TypeEvaluator is FloatEvaluator and the calculation method is as follows:
public Float evaluate(float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); }
The parameters are the interpolation factors, the start value and the end value respectively in the previous step.
3.2 ValueAnimator
ValueAnimator includes all the core functions of the Property Animation, such as the Animation time, start and end attribute values, and the calculation method of the corresponding time attribute values. The application Property Animation has two steps:
- Calculate attribute values
- Execute corresponding actions based on the property value, such as modifying a property of an object.
ValuAnimiator only completes Step 1. To complete step 2, you need to implement the ValueAnimator. onUpdateListener interface, such:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);animation.setDuration(1000);animation.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i("update", ((Float) animation.getAnimatedValue()).toString()); }});animation.setInterpolator(new CycleInterpolator(3));animation.start();
In this example, only some information is output to Logcat, which can be changed to the desired job.
Animator. AnimatorListener
onAnimationStart()onAnimationEnd()onAnimationRepeat()onAnimationCancel
ValueAnimator. AnimatorUpdateListener
OnAnimationUpdate () // listens to this event to perform corresponding operations when the attribute value is updated. ValueAnimator listens to this event to perform corresponding actions, otherwise, Animation is meaningless (it can be used for timing). In ObjectAnimator (inherited from ValueAnimator), attributes are automatically updated. You do not have to listen if necessary. A ValueAnimator parameter is passed in the function, and the current animation attribute value is obtained through getAnimatedValue () of this parameter.
You can inherit the AnimatorListenerAdapter instead of implementing the AnimatorListener interface to simplify the operation. This class defines an empty function body for all functions in the AnimatorListener, in this way, we only need to define the events we want to listen to, instead of implementing each function, we only need to define an empty function body.
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);oa.setDuration(3000);oa.addListener(new AnimatorListenerAdapter(){ public void on AnimationEnd(Animator animation){ Log.i("Animation","end"); }});oa.start();
3.3 ObjectAnimator
Inherited from ValueAnimator, You need to specify an object and an attribute of this object. When the calculation of the Property value is complete, it is automatically set to the corresponding Property of this object, that is, all two steps of Property Animation are completed. In practice, ObjectAnimator is usually used to change a certain attribute of an object. However, ObjectAnimator has certain restrictions. To use ObjectAnimator, the following conditions must be met:
- The object should have a setter function: set <PropertyName> (hump name method)
- In the preceding example, for a factory method like ofFloat, the first parameter is the object name, the second parameter is the attribute name, and the following parameter is a variable parameter. If values... If only one value is set for the parameter, it is assumed as the destination value. The change range of the attribute value is from the current value to the destination value. To obtain the current value, the object must have the getter method of the corresponding property: get <PropertyName>
- If there is a getter method, the type of the response value should be the same as the parameter type of the corresponding setter method.
If the preceding conditions are not met, ObjectAnimator cannot be used instead of ValueAnimator.
tv=(TextView)findViewById(R.id.textview1);btn=(Button)findViewById(R.id.button1);btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f); oa.setDuration(3000); oa.start(); }});
Change the transparency of a TextView from 0 to 1 in 3 seconds.
Depending on the animation objects or attributes, you may need to call the invalidate () function in the onAnimationUpdate function to refresh the view.
3.4 apply multiple animations through AnimationSet
AnimationSet provides a mechanism to combine multiple animations into one, and allows you to set the timing relationships of the animations in the group, such as simultaneous playback and sequential playback.
In the following example, five animations are applied simultaneously:
- Play anim1;
- Simultaneously play anim2, anim3, and anim4;
- Play anim5.
1 |
AnimatorSet bouncer = new AnimatorSet(); |
2 |
bouncer.play(anim1).before(anim2); |
3 |
bouncer.play(anim2).with(anim3); |
4 |
bouncer.play(anim2).with(anim4) |
5 |
bouncer.play(anim5).after(amin2); |
3.5 TypeEvalutors
Calculate the attribute value of the current time based on the start, end, And TimeInterpolation of the attribute. android provides the following evalutor:
- IntEvaluator: the attribute value type is int;
- FloatEvaluator: the attribute value type is float;
- ArgbEvaluator: the property value type is a hexadecimal color value;
- TypeEvaluator: an interface that can be used to customize the Evaluator.
Custom TypeEvalutor is simple. You only need to implement one method, such as the definition of FloatEvalutor:
1 |
public class FloatEvaluator implements TypeEvaluator { |
2 |
public Object evaluate( float fraction, Object startValue, Object endValue) { |
3 |
float startFloat = ((Number) startValue).floatValue(); |
4 |
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); |
Based on the animation execution time and the Interplator of the application, a 0 ~ is calculated ~ 1, that is, the fraction parameter in the evalute function. The above FloatEvaluator should be a good indicator.
3.6 TimeInterplator
Time interplator defines how attribute values change, such as linear Uniform change, slow start, and gradually increase. In Property Animation, It is TimeInterplator and in View Animation is Interplator. The two are the same. Before 3.0, only Interplator is used. After 3.0, code is transferred to TimeInterplator. Interplator inherits from TimeInterplator and has no other internal code.
- AccelerateInterpolator acceleration, slow intermediate acceleration at the beginning
- DecelerateInterpolator slows down, starts fast, and then slows down
- AccelerateDecelerateInterolator accelerates and then slows down.
- AnticipateInterpolator reversely, first changes to the opposite direction and then accelerates playback.
- AnticipateOvershootInterpolator reversely goes beyond the target value, changes in the opposite direction, and then accelerates playback. It then slowly moves beyond the target value.
- BounceInterpolator jumps when it is approaching the destination value. For example, if the destination value is 100, the following values may be 90,100
- CycleIinterpolator loop. The animation loops for a certain number of times. The value changes to a sine function: Math. sin (2 * mCycles * Math. PI * input)
- LinearInterpolator linear, linear and even change
- OvershottInterpolator goes beyond the target value, and then slowly changes to the target value
- TimeInterpolator: an interface that allows you to customize interpolator.
3.7 apply an animation when Layout changes
You can use setVisibility to make the sub-elements in ViewGroup Visible, invisable, or Gone. When the visibility of sub-elements changes, you can apply animations to them and apply these animations through the LayoutTransition class:
transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);
Using setAnimator to apply an animation, the first parameter indicates the application situation. The following four types are supported:
- Animation applied to an element when it becomes Visible
- CHANGE_APPEARING when an element changes to Visible, because the system needs to re-layout some elements that need to be moved, the animation of these elements to be moved
- DISAPPEARING the animation applied to an element when it becomes InVisible
- CHANGE_DISAPPEARING when an element changes to Gone, the animation disappearing from the container will be applied because the system needs to move some elements to the new layout.
The second parameter is Animator.
mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
This function sets the animation duration. The parameters are type and time.
3.8 Keyframes
A keyFrame is a time/value pair. It can be used to define a specific state at a specific time, and different interpolators can be defined between two keyframes, so that a considerable number of animations can be spliced, the ending point of the first animation is the starting point of the second animation. KeyFrame is an abstract class. You must use ofInt (), ofFloat (), ofObject () to obtain the appropriate KeyFrame, and then use PropertyValuesHolder. ofKeyframe to obtain the PropertyValuesHolder object, as shown in the following example:
Keyframe kf0 = Keyframe.ofInt(0, 400);Keyframe kf1 = Keyframe.ofInt(0.25f, 200);Keyframe kf2 = Keyframe.ofInt(0.5f, 400);Keyframe kf4 = Keyframe.ofInt(0.75f, 100);Keyframe kf3 = Keyframe.ofInt(1f, 500);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf4, kf3);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation);rotationAnim.setDuration(2000);
The code above indicates: Set the width attribute value of the btn object to make it:
- Start with Width = 400
- Width = 1/4 when the animation starts
- Width = 1/2 when the animation starts
- Width = 3/4 when the animation starts
- Width = 500 at animation end
The first parameter is the time percentage, and the second parameter is the attribute value at the time of the first parameter. After defining some keyframes, encapsulate them through the PropertyValuesHolder class method ofKeyframe, and then obtain the Animator through ObjectAnimator. ofPropertyValuesHolder. The following code can achieve the same effect:
ObjectAnimator oa=ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);oa.setDuration(2000);oa.start();
3.9 Animating Views
In View Animation, the application of Animation to View does not change the View attributes. The Animation is implemented through its Parent View. When a View is drawn, Parents View changes its rendering parameters, after draw, change the invalidate parameter. Although the View size or rotation angle is changed, the actual attribute of the View remains unchanged. Therefore, the effective area is the area before the animation is applied, for example, if you scale up a button twice, but you still need to zoom in the previous area, the click event can be triggered. To change this, some parameters are added to View in Android 3.0 and corresponding getter/setter functions are added to these parameters (ObjectAnimator uses these functions to change these attributes ):
- TranslationX, translationY: control where the View is located as a delta from its left and top coordinates which are set by its layout container .)
- Rotation, rotationX, rotationY: rotation. rotation is used for 2D rotation angles. The last two values are used in 3D.
- ScaleX, scaleY: Scaling
- X, y: View final coordinates (utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values .)
- Alpha: Transparency
There are three parameters related to location. Taking the X coordinate as an example, you can obtain them through getLeft (), getX (), getTranslateX (). If there is a Button btn2, the coordinates of the layout are (40, 0 ):
// Before the animation is applied, btn2.getLeft (); // 40btn2. getX (); // 40btn2. getTranslationX (); // 0 // apply the translationX animation ObjectAnimator oa = ObjectAnimator. ofFloat (btn2, "translationX", 200); oa. setDuration (1, 2000); oa. start ();/* apply the translationX animation to btn2.getLeft (); // 40btn2. getX (); // 240btn2. getTranslationX (); // 200 * // apply the X animation. Assume that the previous translationX animation ObjectAnimator oa = ObjectAnimator is not applied. ofFloat (btn2, "x", 200); oa. setDuration (1, 2000); oa. start ();/* apply the X animation to btn2.getLeft (); // 40btn2. getX (); // 200btn2. getTranslationX (); // 160 */
No matter how the animation is applied, the original position is obtained through getLeft () and remains unchanged. X is the final position of the View. translationX is the difference between the final position and the initial position of the layout. Therefore, if you use translationX, that is, the number of moves on the original base, and the final number of getX () for X is the value of getLeft () and getTranslationX () and for X animation, the source code is as follows:
case X: info.mTranslationX = value - mView.mLeft; break;
Property Animation can also be defined in XML
- <Set>-AnimatorSet
- <Animator>-ValueAnimator
- <ObjectAnimator>-ObjectAnimator
The XML file should be zoomed in/res/animator/and animations should be applied in the following ways:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator);set.setTarget(myObject);set.start();
3.10 ViewPropertyAnimator
If you want to animation multiple attributes of a View, you can use the ViewPropertyAnimator class. This class optimizes the multi-attribute animation and merges some invalidate () to reduce the refresh View, the class is introduced in 3.1.
The following two sections of code achieve the same effect:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
myView.animate().x(50f).y(100f);