Animation classification
Android animation can be divided into 3 kinds: View animation, frame animation and property animation, property animation is a new feature of API11, in the low version is not directly using the property animation, but can be implemented with nineoldandroids (but the essence or Viiew animation). This article focuses on the following knowledge:
1,view animations and custom view animations.
Some special usage scenarios for 2,view animations.
3, a comprehensive introduction to the property animation.
4, use some precautions for animations.
View Animations
The four transformations of the view animation correspond to the four subclasses of animation: Translateanimation (panning animation), scaleanimation (zoom animation), Rotateanimation (rotational animation) and alphaanimation (transparency animation), they can be dynamically created with code or can be defined using XML, and it is recommended to use better-readable XML to define it.
The <set> tag represents a collection of animations, corresponding to the Animationset class, which can contain several animations, and his internal can also nest other animation collections. Android:interpolator represents the interpolation used by the animation collection, and the interpolator affects the animation speed, such as the non-uniform animation requires the interpolation to control the animation playback process.
Android:shareinterpolator indicates whether the animation in the collection shares the same interpolator as the collection, and if the collection does not specify an interpolator, the child animation needs to specify the desired interpolator or default values separately.
Animation can add process monitoring to the view animation through the Setanimationlistener method.
Custom View animations only need to inherit the abstract class animation, and override the Initialize and Applytransformation methods to do some initialization work in the Initialize method, It is necessary to use camera to simplify the process of rectangle transformation in applytransformation.
Frame animation is a set of pre-defined pictures that play like movies, simple to use but prone to oom, and try to avoid using too many larger images.
View Animation application scene layoutanimation action on ViewGroup, for ViewGroup to specify an animation, when his child elements will have this animation when the appearance, the ListView used more, Layoutanimation is also a view animation.
Code implementation:
<?xml version= "1.0" encoding= "Utf-8"? ><layoutanimation xmlns:android= "Http://schemas.android.com/apk/res /android "android:animationorder=" normal "android:delay=" 0.3 "android:animation=" @anim/anim_item "/>//--- AnimationOrder represents the order of animation for child elements, with three options://normal (sequential display), reverse (reverse display), and random (randomly displayed). <?xml version= "1.0" encoding= "Utf-8"? ><set xmlns:android= "Http://schemas.android.com/apk/res/android" android:duration= "android:shareinterpolator=" "true" > <alpha android:fromalpha= "0.0" android: Toalpha= "1.0"/> <translate android:fromxdelta= "+" android:toxdelta= "0"/></set>
First, referencing layoutanimation in the layout
<listview android:id= "@+id/lv" android:layout_width= "match_parent" android:layout_height= "0DP" android:layout_weight= "1" android:layoutanimation= "@anim/anim_layout"/>
The second type of code is used
Animation Animation = Animationutils.loadanimation (this, r.anim.anim_item); Layoutanimationcontroller controller = new Layoutanimationcontroller (animation); Controller.setdelay (0.5f); Controller.setorder (Layoutanimationcontroller.order_normal); listview.setlayoutanimation (Controller);
Frame animation Frames-by-frame animation (frame-by-frame animations) is literally a frame-by-frame playback of a picture, similar to the effect of playing a movie. Unlike the view animation, the Android system provides a class animationdrawable to implement frame animation, frame animation is relatively simple, we look at an example on the line.
<?xml version= "1.0" encoding= "Utf-8"? ><animation-list xmlns:android= "http://schemas.android.com/apk/res/ Android " android:oneshot=" false "> <item android:drawable=" @mipmap/lottery_1 " android: Duration= "/>" //... Omit many <item android:drawable= "@mipmap/lottery_6" android:duration= "/></animation-list" >
And then
Imageview.setimageresource (R.drawable.frame_anim); Animationdrawable animationdrawable = (animationdrawable) imageview.getdrawable (); Animationdrawable.start ();// Start start, close stop
Property Animation Property Animation is a feature of Android 3.0 new (API 11), unlike the previous view animation (seen that the view animation, such as the implementation of the displacement is not really the location of the move, but the implementation of some simple visual effects). Property animation has made a great expansion of the previous animation, it is no exaggeration to say that the property animation can achieve any animation effect, because the object is a property (object), property animation has several concepts need our attention,
Valueanimator, Objectanimator, Animatorset and so on.
Property Animation Action Property 1, property animation can animate the properties of any object, not just the view, property animation default interval 300ms, the default frame rate 10ms/frame.
2, look at a piece of code
<set android:ordering=["Together" | "Sequentially"]> <objectanimator android:propertyname= "string" android:duration= "int" android:valuefrom= "float | int | Color " android:valueto=" float | int | color " android:startoffset=" int " android:repeatcount=" int " android:repeatmode=["Repeat" | "Reverse"] android:valuetype=["Inttype" | "Floattype"]/> <animator android:duration= "int" android:valuefrom= "float | int | color" android:valueto= "float | int | Color " android:startoffset=" int " android:repeatcount=" int " android:repeatmode=[" Repeat "| "Reverse"] android:valuetype=["Inttype" | "Floattype"]/> <set> ... </set></set>
<set> it stands for a Animatorset object. There is a ordering property, which specifies the order in which the animation is played.
<objectAnimator> it represents a Objectanimator object. It has a lot of attributes, and it's what we need to know. Android:propertyname-------property names, such as "Alpha" and "BackgroundColor" for a View object.
Android:valuefrom--------Change Start value
Android:valueto------------Change End value
Android:valuetype-------Variable value type, which has two values: Inttype and Floattype, and the default value Floattype.
Android:duration---------duration android:startoffset---------animation start delay time Android:repeatcount--------Repetition, 1 means infinite repetition, The default is -1android:repeatmode repeating mode, provided that Android:repeatcount is-1, which has two values: "Reverse" and "repeat", respectively, representing the reverse and sequential direction.
<animator>
It corresponds to the Valueanimator object. It mainly has the following properties.
Android:valuefrom
Android:valueto
Android:duration
Android:startoffset
Android:repeatcount
Android:repeatmode
Android:valuetype
After defining a set of animations, how do we make it work?
Animatorset set = (Animatorset) animatorinflater.loadanimator (mycontext, r.anim.property_animator); Set.settarget (MyObject);//myobject represents the object of Action Set.start ();
Interpolator and Estimator
The function of the time Interpolator (Timeinterpolator) is to calculate the percentage of the current attribute value change based on the percentage of elapsed time, and the system preset has linearinterpolator (linear interpolator: Constant speed animation), Acceleratedecelerateinterpolator (Accelerated deceleration interpolator: Animation two slow middle fast), decelerateinterpolator (deceleration interpolator: animation getting slower).
Note: There are a lot of interpolator here, you can look at my previous about the interpolator explanation.
The function of the estimator (Typeevaluator) is to calculate the changed attribute value based on the percentage of the current property change. The system is preset with Intevaluator, Floatevaluator, Argbevaluator.
Give me a simple example.
public class Intevaluator implements typeevaluator<integer> {public Integer evaluate (float fraction, Integer start Value, Integer endvalue) { int startint = Startvalue; return (int) (Startint + fraction * (endvalue-startint)); }}
The above code is the total percentage of the current attribute.
Interpolator and Estimator In addition to the system, we can also customize the implementation, custom Interpolator needs to implement Interpolator or timeinterpolator; The Custom estimator algorithm needs to implement Typeevaluator.
The Property Animation Listener Property Animation listener is used to listen for the animation playback process, there are two main interfaces: Animatorupdatelistener and Animatorlistener. Animatorlistener
public static interface Animatorlistener { void Onanimationstart (Animator animation);//animation start void Onanimationend (Animator animation); Animation ends void Onanimationcancel (Animator animation);//animation cancellation void Onanimationrepeat (Animator animation); Animation repeat play}
Animatorupdatelistener
public static interface Animatorupdatelistener { void Onanimationupdate (Valueanimator animator);}
Application Scenarios
Here we first ask a question: Add an animation to the button, so that the button in 2 seconds to increase the bandwidth from the current width to 500DP, or you will say, very simple, directly with the view animation can be achieved, view animation does not have a zoom animation, but you can try, The view animation does not support changing the width and height. Button inherited from Textview,setwidth is TextView, so it is not possible to do setwidth directly to the button. So what do we do? For the above questions, the official website API gives the following scenarios:
- Add the Get and set methods to your object, if you have permission.
- Use a class to wrap the original object and indirectly improve the get and set methods
- Adopt Valueanimator, monitor the animation execution process, realize the property change
With the above instructions, we generally understand that to achieve the effect of the beginning of the problem, we need to use an indirect class to implement the Get and set methods or to implement a valueanimator. The first is to encapsulate a class to implement the Get and set methods, which is also our common, highly scalable
public class Viewwrapper {private View target, public viewwrapper (View target) { This.target = target,} public int G Etwidth () { return Target.getlayoutparams (). width;} public void setwidth (int width) { Target.getlayoutparams ( ). width = width; Target.requestlayout (); }}
Second, the use of valueanimator, monitoring the animation process.
private void Startvalueanimator (final View target, final int start, final int end) { Valueanimator valueanimator = Val Ueanimator.ofint (1, +); Valueanimator.addupdatelistener (New Valueanimator.animatorupdatelistener () { private intevaluator mEvaluation = New Intevaluator ();//Create an shaping estimator as a temporary variable @Override public void Onanimationupdate (Valueanimator animation) { //Gets the current animation's progress value between 1~100 int currentvalue = (int) animation.getanimatedvalue (); Get current progress in proportion to the entire animation process, float, 0~1 between float fraction = animation.getanimatedfraction (); Call the estimator, calculate the width by scale int targetwidth = mevaluation.evaluate (fraction, start, end); Target.getlayoutparams (). width = targetwidth; Set to the Action object, refresh page target.requestlayout (); } );}
How property animations workProperty animation works by constantly calling the Get/set method on the object to change the initial and final values, then set to the animated properties. Then through the message mechanism (Handler (but here the Handler is not our usual Handler, but Animationhandler, it is essentially a runable) and looper to the animation execution), Through the code we found that it tuned the JNI code, but this we do not care, we directly see Objectanimator.start ()
private void Start (Boolean playbackwards) {if (looper.mylooper () = = null) {throw new Androidruntimeexce Ption ("Animators May is run on Looper threads"); } else {this.mplayingbackwards = playbackwards; this.mcurrentiteration = 0; this.mplayingstate = 0; This.mstarted = true; This.mstarteddelay = false; ((ArrayList) Spendinganimations.get ()). Add (this); if (This.mstartdelay = = 0L) {this.setcurrentplaytime (This.getcurrentplaytime ()); this.mplayingstate = 0; This.mrunning = true; if (this.mlisteners! = null) {ArrayList Animationhandler = (ArrayList) this.mListeners.clone (); int numlisteners = Animationhandler.size (); for (int i = 0; i < numlisteners; ++i) {((Animatorlistener) animationhandler.get (i)). onanimations Tart (this); } }} Valueanimator.animationhandler Var5 = (valueanimator.animationhandler) Sanimationhan Dler.get (); if (VAR5 = = null) {VAR5 = new Valueanimator.animationhandler (null); Sanimationhandler.set (VAR5); } var5.sendemptymessage (0); } }
private static final threadlocal<arraylist<valueanimator>> sanimations = new ThreadLocal () {protected Arraylist<valueanimator> InitialValue () {return new ArrayList (); } }; private static final threadlocal<arraylist<valueanimator>> spendinganimations = new ThreadLocal () {Pro tected arraylist<valueanimator> InitialValue () {return new ArrayList (); } }; private static final threadlocal<arraylist<valueanimator>> sdelayedanims = new ThreadLocal () {protecte D arraylist<valueanimator> InitialValue () {return new ArrayList (); } }; private static final threadlocal<arraylist<valueanimator>> sendinganims = new ThreadLocal () {protected Arraylist<valueanimator> InitialValue () {return new ArrayList (); } }; private static final threadlocal<arraylist<valueanimator>> sreadyanims = new ThreadloCal () {protected arraylist<valueanimator> InitialValue () {return new ArrayList (); } };
Here the system how to calculate the animation of each frame, look at the following code
void Animatevalue (float fraction) { fraction = this.mInterpolator.getInterpolation (fraction); this.mcurrentfraction = fraction; int numvalues = this.mValues.length; int numlisteners; for (numlisteners = 0; numlisteners < numvalues; ++numlisteners) { This.mvalues[numlisteners].calculatevalue ( fraction); } if (this.mupdatelisteners! = null) { numlisteners = This.mUpdateListeners.size (); for (int i = 0; i < numlisteners; ++i) { ((valueanimator.animatorupdatelistener) this.mUpdateListeners.get (i)). Onanimationupdate (this);}}}
But we know to change the animation, must call the Get/set method, then we focus on the relevant code. This code is in the SetProperty method
public void SetProperty { if (this.mvalues! = null) { Propertyvaluesholder Valuesholder = this . mvalues[0]; String oldname = Valuesholder.getpropertyname (); Valuesholder.setproperty (property); This.mValuesMap.remove (oldname); This.mValuesMap.put (This.mpropertyname, Valuesholder); } if (this.mproperty! = null) { this.mpropertyname = Property.getname (); } This.mproperty = property; This.minitialized = false; }
Here is a propertyvaluesholder, as the name implies this is a class of manipulating data, and our adapter holder, the method's Get method mainly uses the reflection.
private void Setupvalue (Object target, keyframe KF) { if (this.mproperty! = null) { Kf.setvalue ( This.mProperty.get (target)); } try { if (This.mgetter = = null) { Class e = Target.getclass (); This.setupgetter (e); } Kf.setvalue (This.mGetter.invoke (target, New object[0])); catch (InvocationTargetException var4) { log.e ("Propertyvaluesholder", var4.tostring ()); } catch ( Illegalaccessexception var5) { log.e ("Propertyvaluesholder", var5.tostring ()); } }
Code to see this, interested in can go to see the source
Things to note about using property animations
When using frame animation, when the number of pictures and the picture resolution is large, it is easy to get OOM, you should pay attention to avoid using frame animation.
When using an infinite loop property animation, even if the activity exits, it will cause the activity to fail to release and thus cause a memory leak .
View animation is a view of the image animation, not really change the state of the view, so sometimes the animation is completed after the view can not be hidden (setvisibility (View.gone) failure), this time call view.clearanimation () clean up the view animation to resolve.
Do not use PX, the use of PX will result in different effects on different devices.
The view animation is an image of the view animation, the real position of the view is not changed, it will lead to click on the view animation position after the touch event does not respond, property animation does not exist this problem.
Using hardware acceleration during animation can improve the smoothness of your animation.
Animation under 3.0 compatibility problems, special scenarios may not work properly, need to do a good job of adaptation.
Android animation in-depth analysis