1, overview
Android offers several types of animations: View Animation, drawable Animation, property Animation. View animation is fairly simple, but it can only support simple scaling, translation, rotation, transparency, basic animation, and has certain limitations. For example, you want the view to have a toggle animation of the color, you want to be able to use 3D rotation animation; you want the view position to be the current position when the animation stops; These view animation are not possible. This is the reason for the property animation, this article is to introduce the use of property animation in detail. The
Property animation system is a fairly robust framework that can animate almost any object. You can define an animation to periodically change any object's property values, regardless of whether the object is displayed on the screen. The property animation modifies the attribute value (the field value in the object) at a certain interval. To animate, you need to specify the corresponding attributes of the object (such as the screen location of the object), as well as the length of the animation, the animation time interval. The
Property animation system allows you to set the following animation elements:
(1) Duration: Specifies the duration of the animation. The default duration is 300 milliseconds.
(2) image interpolation: Specifies how the value of the property is changed, expressed as a function about the time the animation has been displayed.
(3) Repeat number and mode: Specifies whether the animation is looping, and the number of repetitions. You can also specify whether the animation plays backwards. It can be set to forward playback and then back playback, so reciprocating until the set number of repetitions is reached.
(4) Animation collection: You can divide the animation into multiple logical groups for simultaneous playback, sequential playback, or an interval of time.
(5) Frame Refresh interval: Specifies the frequency at which animation frames are refreshed. The default is to refresh every MS, but the actual amount of refresh the application can perform depends on how busy the system is as a whole and how well the system supports the timer.
2. Related API
Property Animation name Incredible is to animate the way the object's properties, we first need to understand several attributes:
(1) The duration of the duration animation, the default 300ms.
(2) Time interpolation: Difference, at first glance do not know what, but I said Linearinterpolator, acceleratedecelerateinterpolator, we must know what it is, Defines the rate of change for an animation.
(3) Repeat count and behavior: number of repetitions, and recurrence pattern; You can define how many times to repeat, start from scratch, or reverse when you repeat.
(4) Animator sets: Animation set, you can define a set of animations, either executed together or sequentially executed.
(5) Frame Refresh delay: Frame refresh delay, for your animation, how often to refresh the frame, the default is 10ms, but ultimately rely on the current state of the system;
Related classes:
(1) Objectanimator animation of the implementation of the class, described in detail later
(2) Valueanimator animation of the implementation of the class, described in detail later
(3) Animatorset is used to control the execution of a group of animations: linear, together, each animation successively executed, etc.
(4) Animatorinflater user loads an XML file for a property animation
(5) Typeevaluator type valuation, mainly used to set the value of animation action properties.
(6) Timeinterpolator time interpolation, which has been described above.
In general, the property animation is the animation of the execution class to set the animation operation of the object's properties, duration, start and end of the property values, time difference, and so on, and then the system will dynamically change the properties of the object according to the parameters.
3, Objectanimator implementation of animation
The reason why I chose Objectanimator as the first ~ ~ is that this implementation is the simplest one-line code, seconds to achieve animation, the following look at an example:
Layout file:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:tools= "http:// Schemas.android.com/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>
Very simple, just a picture of a sister ~
Activity code:
Package com.example.zhy_property_animation;
Import Android.animation.ObjectAnimator;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.view.View;
public class Objectanimactivity extends activity
{
@Override
protected void OnCreate (Bundle Savedinstancestate)
{
super.oncreate (savedinstancestate);
Setcontentview (R.layout.xml_for_anim);
}
public void Rotateyanimrun View
{
objectanimator//
. Offloat (view, RotationX, 0.0F, 360.0F)//
. Setduration//
. Start ();
}
}
Effect:
is not a line of code to achieve simple animation ~ ~
For Objectanimator:
(1) provides Ofint, Offloat, Ofobject, which are the elements that animate the action, the properties of the action, the start of the animation, the end, and any property values in the middle.
When setting only one for a property value, it is assumed that the value of the property is, of course, started (Getpropname reflection gets), and the value set is the end point. If set two, then one for the start, one for the end ~ ~ ~
In the process of updating the animation, you will constantly invoke the attributes of the Setpropname update element, all using Objectanimator to update a property, you must have getter (set a property value) and setter method ~
(2) If you are manipulating the object's attribute method, such as the Setrotationx of the previous example, if the view's redraw is not called internally, you will need to manually invoke it yourself in the following way.
Anim.addupdatelistener (New Animatorupdatelistener ()
{
@Override public
void Onanimationupdate ( Valueanimator animation)
{
// view.postinvalidate (); view.invalidate ();
}
);
(3) Look at the above example, because the set of the operation of the property only one, then if I want an animation to be able to make the view can be reduced, and can fade out (3 attributes Scalex,scaley,alpha), only use objectanimator how to do?
The idea is not very good, may say use animatorset ah, this see is a bunch of animation plug together to execute, but I have to use a objectanimator instance to realize it ~ Look at the code below:
public void Rotateyanimrun (final view view)
{
Objectanimator anim = objectanimator//
. Offloat (View, Zhy) 1.0F, 0.0F)//(
setduration);//
Anim.start ();
Anim.addupdatelistener (New Animatorupdatelistener ()
{
@Override public
void Onanimationupdate ( Valueanimator animation)
{
float cval = (float) animation.getanimatedvalue ();
View.setalpha (cval);
View.setscalex (cval);
View.setscaley (Cval);
}
);
To set the property of that string, casually write a property that the object does not, that is, no matter ~ ~ We only need it according to the time interpolation and duration of the calculation of that value, we manually call the ~
Effect:
This example is to explain, and sometimes change the idea not to be constrained by the API, the use of some of the API to provide the function can also achieve fun effect ~ ~ ~
For example: you want to achieve the effect of parabolic line, horizontal direction 100px/s, vertical acceleration 200px/s*s, how to achieve it ~ ~ can use their own objectanimator try ~
(4) There is actually a simpler way to implement an animation that changes multiple effects: 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 implementation of animation
similar to objectanimator usage, take a quick look at the animated code that moves vertically with the view:
public void Verticalrun (view view)
{
Valueanimator animator = valueanimator.offloat (0, Mscreenheight
- Mblueball.getheight ());
Animator.settarget (Mblueball);
Animator.setduration (1000). Start ();
Give you the feeling is not, pit dad Ah, this and valueanimator have a yarn difference ~ But look carefully, you will see that there is no set the operation of the property ~ ~ that is, the above code is no effect, no attributes specified ~
This is the difference with Valueanimator: Valueanimator does not operate on attributes, you may ask what is the benefit? Do I have to set it manually?
Benefits: Properties of objects that do not need to be manipulated must have getter and setter methods, and you can manipulate any attribute based on the current animation's value, and remember the example above "I want an animation that allows view to shrink and fade out (3 attribute ScaleX, Scaley,alpha) "? That's the way it is.
Instance:
Layout file:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http:// Schemas.android.com/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:la Yout_width= "Fill_parent" android:layout_height= "Wrap_content" android:layout_alignparentbottom= "true" Andro id:orientation= "Horizontal" > <button android:layout_width= "wrap_content" android:layout_height = "Wrap_content" android:onclick= "Verticalrun" android:text= "vertical"/> <button T_width= "Wrap_content" android:layout_height= "wrap_content" android:onclick= "Paowuxian" android:text= "Parabola"/> </LinearLayout> &lT;/relativelayout>
A small ball in the upper left corner, two buttons on the bottom ~ Let's look at a free fall Code first:
/**
* Free Fall
* @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 ()
{
@Override public
void Onanimationupdate (valueanimator animation)
{
Mblueball.settranslationy ((Float) Animation.getanimatedvalue ();}
}
);
Unlike Objectanimator is that we set the update of the element properties ~ Although a few lines of code, but seemingly improve flexibility ~
Here's another example, if I want the ball parabolic movement "to achieve the effect of parabola, horizontal direction 100px/s, vertical acceleration 200px/s*s", analysis, seemingly only with time, but according to the change of time, horizontal and vertical movement rate is different, how do we achieve it? It's time to rewrite Typevalue, because we need to return to the object two values at the same time, x current position, y current position:
Code:
/** * 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 @Override Public PointF evaluate (float fraction, PointF startvalue, PointF endvalue) {log.e (TAG, FRA
ction * 3 + "");
X Direction 200px/s, then y direction 0.5 * t PointF point = new PointF ();
point.x = * fraction * 3;
Point.y = 0.5f * (fraction * 3) * (fraction * 3);
return point;
}
});
Valueanimator.start (); Valueanimator.addupdatelistener (New Animatorupdatelistener () {@Override public void onanimationupdate ( Valueanimator animation) {PointF point = (Pointf) Animation.getanimatedvalue ();
Mblueball.setx (Point.x);
Mblueball.sety (POINT.Y);
}
});
}
As you can see, because the ofint,offloat and so on cannot use, we have customized a typevalue, each time returns a PointF object according to the current time, (PointF and Point's difference is the x,y unit one is float, one is int; Rectf,rect also) pointf contains the X,y's current position ~ then we get in the listener and dynamically set the properties:
Effect Chart:
There are two iron balls with wooden ball at the same time the feeling of landing ~ ~ Yes, I should get two balls ~~ps: If the physics formula is wrong, when not see ha
Custom Typeevaluator incoming generics can design a bean of their own according to their needs.
Well, we've explained the Valueanimator and Objectanimator animations separately, how to use some of the APIs to update their properties, and customize the typeevaluator to achieve our needs; but we didn't say how to design interpolation, In fact, I think that the interpolation of the default that a series of implementation-class enough ~ ~ Very little, will own to design a super abnormal ~ mm ~ so: a little.
5, monitor the animation events
for animation, usually some auxiliary effects, such as I want to delete an element, I may want to be a fading effect, but ultimately to delete, not your transparency is not, but also occupy the position, so we need to know how the animation end.
So we can add an animated listener:
public void fadeout (view view) {Objectanimator Anim = objectanimator.offloat (Mblueball,
"Alpha", 0.5f);
Anim.addlistener (New Animatorlistener () {@Override public void Onanimationstart (animator animation)
{LOG.E (TAG, "Onanimationstart"); @Override public void Onanimationrepeat (animator animation) {//TODO auto-generated met
Hod stub log.e (TAG, "onanimationrepeat");
@Override public void Onanimationend (animator animation) {LOG.E (TAG, "onanimationend");
ViewGroup parent = (ViewGroup) mblueball.getparent ();
if (parent!= null) Parent.removeview (Mblueball); @Override public void Onanimationcancel (animator animation) {//TODO auto-generated met
Hod stub log.e (TAG, "Onanimationcancel");
}
});
Anim.start (); }
This will be able to monitor the beginning of the animation, end, canceled, repeat events ~ but sometimes feel that I just know the end of the line, so long code I can not receive, then you can use Animatorlisteneradapter
Anim.addlistener (New Animatorlisteneradapter ()
{
@Override public
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 the empty implements all the methods ~
Effect Chart:
Animator also has the Cancel () and End () method: The Cancel animation stops immediately, stops at the current location, and ends the animation directly to the final state.
6, the use of Animatorset
Example:
Layout file:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http:// Schemas.android.com/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 hyperactivity
Painting together "/> <button android:layout_width= wrap_content" android:layout_height= "Wrap_content"
android:onclick= "Playwithafter" android:text= "Multiple animation in order"/> </LinearLayout> </RelativeLayout>
Continue playing Ball ~
Code:
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;
@Override protected 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 ()); Two animations simultaneously executing animset.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 concurrently executes * ANIM4 then executes * * 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 here:
First: The use of Playtogether two animation at the same time, of course, and playsequentially in turn to execute ~ ~
Second: If we have a bunch of animations, how to use the Code control order, such as 1, 2 at the same time; 3 in 2; 4 before 1 wait ~ is the effect 2.
One thing to note: Animset.play (). with (); It is also supported chained programming, but don't think about it like Animset.play (ANIM1). with (ANIM2). Before (ANIM3). This is not possible, the system will not be based on the long string you write to determine the order, so trouble you to follow the example above, write a few more lines:
Effect Chart: