Property Animations
satya - Monday, November 07, 2011 9:54:22 AM
Start with an animator
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(500);
anim.start();
satya - Monday, November 07, 2011 9:55:15 AM
Provide a callback impl
anim.addUpdateListener(
new ValueAnimator.AnimatorUpdateListener()
{
public void onAnimationUpdate(ValueAnimator animation)
{
Float value = (Float) animation.getAnimatedValue();
// do something with value...
}
}
);
satya - Monday, November 07, 2011 9:56:00 AM
An XML of the same
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:valueType="intType"/>
satya - Monday, November 07, 2011 1:48:20 PM
Here is how you can change the alpha of a text view
private void animateTextView(TextView tv)
{
//Fade out if it is visible, making it invisible
if (tv.getAlpha() != 0)
{
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
fadeOut.start();
}
//Fade in if it is invisible, makign it visible
else
{
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
fadeIn.start();
}
}
satya - Monday, November 07, 2011 1:55:16 PM
api: ValueAnimator
See this link to see what methods and attributes, callbacks are avialble.
satya - Monday, November 07, 2011 1:56:22 PM
Animation package API
See all the classes in the animation package here
satya - Monday, November 07, 2011 2:02:23 PM
The AnimationSetBuilder api
satya - Monday, November 07, 2011 2:17:24 PM
Here is how to fade out and fade in through an animator set
private void animateTv1(TextView m_tv)
{
m_tv.setAlpha(1f);
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
AnimatorSet as = new AnimatorSet();
as.playSequentially(fadeOut,fadeIn);
as.setDuration(2000); //2 secs
as.start();
}
satya - Monday, November 07, 2011 2:18:02 PM
AnimatorSet is an Animator by itself
So chaining is possible
satya - Tuesday, November 08, 2011 1:39:42 PM
What is AnimatorSet.Builder?
This is purely a utility class that allows you establish reslationship between the individual animations in a set. Whether to run the animations serially, parallely or to run before or to run after etc.
if you can do this relationships with the animator set itself explicitly then you can use it as such.
satya - Tuesday, November 08, 2011 1:41:36 PM
Methods on AnimatorSet
playTogether(list of animators)
playSequentially(list of animators)
satya - Tuesday, November 08, 2011 1:43:40 PM
using play and builder
public void testAnimationBuilder(View v)
{
m_tv.setAlpha(1f);
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
AnimatorSet as = new AnimatorSet();
as.play(fadeOut).before(fadeIn);
as.setDuration(2000); //2 secs
as.start();
}
satya - Tuesday, November 08, 2011 1:46:59 PM
Note worthy
You start with a single animator
you will use "play" against that single animator to start the builder. This first animator becomes the animator of focus. All subsequent animations used by
before after with
are in relation to the first animator.
In the end you start the animator set and not the builder. The duration and interpolators etc also apply to the animator set and animators and not to the builder.
satya - Tuesday, November 08, 2011 1:48:12 PM
what have i go to so far
valueanimator
objectanimator
animatorset
animatorset.builder
xml animators
view properties to animate
satya - Tuesday, November 08, 2011 1:49:26 PM
See this link to see fragment animations and some stock animation xml files
See this link to see fragment animations and some stock animation xml files
satya - Tuesday, November 08, 2011 1:52:32 PM
see this link as well: sdk property animations
satya - Tuesday, November 08, 2011 1:59:00 PM
This link has a list of interpolators
satya - Tuesday, November 08, 2011 2:21:20 PM
Understadn view property animator by reading this blog
satya - Tuesday, November 08, 2011 2:22:25 PM
Understand layouttransition class
satya - Tuesday, November 08, 2011 3:01:52 PM
ObjectAnimator.ofFloat(m_tv, 'alpha', 0f, 1f, 2f, ....)
Constructs and returns an ObjectAnimator that animates between int values. A single value implies that that value is the one being animated to. Two values imply a starting and ending values. More than two values imply a starting value, values to animate through along the way, and an ending value (these values will be distributed evenly across the duration of the animation).
satya - Tuesday, November 08, 2011 3:09:58 PM
Using propertyvaluesholder
//Go to 50 on x
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
//Go to 100 on y
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
//Do them both x and y
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
satya - Tuesday, November 08, 2011 3:25:26 PM
what can you tell about the view property animator
it is instigated by calling "animate()" on any view
The sets on the view property animator are cumulative for this frame: that is a bit similar to OpenGL if I remember right
All the animations are clubbed and played when the UI thread gets around to it on subsequent frame refreshes
satya - Tuesday, November 08, 2011 3:26:02 PM
In Android how can i set start values for a view property animator?
In Android how can i set start values for a view property animator?
Search for: In Android how can i set start values for a view property animator?
satya - Tuesday, November 08, 2011 3:26:25 PM
viewpropertyanimator
viewpropertyanimator
Search Google for: viewpropertyanimator
Search Android Developers Group for: viewpropertyanimator
Search Android Beginers Group for: viewpropertyanimator
satya - Wednesday, November 09, 2011 10:04:23 AM
Moving a view from south-east to north-west
public void testPropertiesHolder(View m_tv)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
//Set the view to the right bottom
m_tv.setX(w);
m_tv.setY(h);
//Move the view to the right top
//set x to original x
PropertyValuesHolder pvhX =
PropertyValuesHolder.ofFloat("x", x);
//set y to original y
PropertyValuesHolder pvhY =
PropertyValuesHolder.ofFloat("y", y);
ObjectAnimator oa
= ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhX, pvhY);
oa.setDuration(5000); //2 secs
oa.start();
}
satya - Wednesday, November 09, 2011 10:13:25 AM
Two distinct packages
android.animation
android.view.animation
satya - Wednesday, November 09, 2011 10:16:29 AM
android.animation
Key classes
animators value object animatorset PropertyValuesHolder TypeEvaluator
satya - Wednesday, November 09, 2011 10:18:06 AM
android.view.animation
Key classes
interpolators Older animations scale translate rotate transform
satya - Wednesday, November 09, 2011 10:21:30 AM
Setting an interpolator on an animator
ObjectAnimator oa
= ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhX, pvhY);
oa.setDuration(5000); //5 secs
oa.setInterpolator(
new AccelerateDecelerateInterpolator());
satya - Wednesday, November 09, 2011 10:22:38 AM
The x and y coordinates in a transforming view relates to its parent
x=0 and y=0 referes to the relative top-left corner of the parent view.
satya - Wednesday, November 09, 2011 1:42:23 PM
By default a layout clips its children
By default a layout clips its children
satya - Wednesday, November 09, 2011 1:44:08 PM
Remember that a last linear layout may take all the space?
Unless you pay attention and control the height of the linear layout it may take the entire space left in the activity if it is the last one. To control it otherwise use the wrap_content options for height instead of match or fill parent.
satya - Wednesday, November 09, 2011 2:48:43 PM
Here is a way you can animate a view using points
public class MyAnimatableView
{
PointF curPoint = null;
View m_v = null;
public MyAnimatableView(View v)
{
curPoint = new PointF(v.getX(),v.getY());
m_v = v;
}
public PointF getCurPointF()
{
return curPoint;
}
public void setPoint(PointF p)
{
curPoint = p;
m_v.setX(p.x);
m_v.setY(p.y);
}
}
satya - Wednesday, November 09, 2011 2:59:10 PM
idea is....
Keep a local pointer to a view such as a text view. Keep this parent object in your activity as a local variable.
Have a set method on the view that can change what you want to change such as the position of the view.
All you have to do now is to find a mechanism to invoke "setPoint" frequently.
This can be done by an object animator
Pass the object animator this object, and the name of the method and the startign point and the ending point.
This is done through object animators adn type evaluators. Here is the driver code for this first and then I will show you the type evaluator that knows to vary points over time
satya - Wednesday, November 09, 2011 3:00:59 PM
Here is how you would use a type evaluator with an object animator
public void testTypeEvaluator(TextView m_tv,
MyAnimatableView m_atv)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
ObjectAnimator tea =
ObjectAnimator.ofObject(m_atv
,"point"
,new MyPointEvaluator()
,new PointF(w,h)
,new PointF(x,y));
tea.setDuration(5000);
tea.start();
}
satya - Wednesday, November 09, 2011 3:01:43 PM
Here is the code for the MyPointEvaluator
public class MyPointEvaluator
implements TypeEvaluator<PointF>
{
public PointF evaluate(float fraction,
PointF startValue,
PointF endValue)
{
PointF startPoint = (PointF) startValue;
PointF endPoint = (PointF) endValue;
return new PointF(
startPoint.x + fraction * (endPoint.x - startPoint.x),
startPoint.y + fraction * (endPoint.y - startPoint.y));
}
}
satya - Wednesday, November 09, 2011 3:07:33 PM
The previous animations are now considered legacy!!
satya - Wednesday, November 09, 2011 3:08:15 PM
New animations gets their own resource type: res/animator
New: /res/animator
old: /res/anim
satya - Wednesday, November 09, 2011 3:09:17 PM
Supported xml tags
ValueAnimator - <animator>
ObjectAnimator - <objectAnimator>
AnimatorSet - <set>
satya - Wednesday, November 09, 2011 3:13:19 PM
See this link to see a quick guide to using animations XMLs
satya - Wednesday, November 09, 2011 3:13:39 PM
Use this link for a reference of each of the xmls
satya - Wednesday, November 09, 2011 3:16:04 PM
A sample set
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:valueFrom="0"
android:valueTo="1280"
android:valueType="floatType"
android:propertyName="y"
android:duration="2000" />
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="2000" />
</set>
satya - Wednesday, November 09, 2011 3:24:40 PM
If this file is called res/animator/fadein.xml then...
public void sequentialAnimationXML(TextView m_tv)
{
m_tv.setAlpha(1f);
AnimatorSet set = (AnimatorSet)
AnimatorInflater.loadAnimator(this,
R.animator.fadein);
set.setTarget(m_tv);
set.start();
}
satya - Wednesday, November 09, 2011 4:16:37 PM
Here is an example of key frame animation
public void testKeyFrames(View v)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
//Start frame : 0.2
//alpha: 0.8
Keyframe kf0 = Keyframe.ofFloat(0.2f, 0.8f);
//Middle frame: 0.5
//alpha: 0.2
Keyframe kf1 = Keyframe.ofFloat(.5f, 0.2f);
//end frame: 0.8
//alpha: 0.8
Keyframe kf2 = Keyframe.ofFloat(0.8f, 0.8f);
PropertyValuesHolder pvhAlpha =
PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);
PropertyValuesHolder pvhX =
PropertyValuesHolder.ofFloat("x", w, x);
//end frame
ObjectAnimator anim =
ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhAlpha,pvhX);
anim.setDuration(5000);
anim.start();
}
satya - Wednesday, November 09, 2011 4:29:23 PM
layout transitions are nicely documented here as part of the api
layout transitions are nicely documented here as part of the api
satya - Thursday, November 10, 2011 9:06:00 AM
Let me summarize the layout transistions
To enable layout transitions on a view group you will do
viewgroup.setLayoutTransition( new LayoutTransition() );
satya - Thursday, November 10, 2011 9:07:00 AM
The layouttransition object comes with its own set of 4 animators
The layout transistion comes with its own set of 4 animators for each of the 4 transitions.
satya - Thursday, November 10, 2011 9:09:33 AM
The transitions are
add a view (appearing)
change appearing (rest of the items in layout)
remove a view (disappearing)
change disappearing (rest of the items in layout)
satya - Thursday, November 10, 2011 9:17:54 AM
Couple of useful methods
LayoutTransition lt
= new LayoutTransition();
someLayout.setLayoutTransition(lt);
//obtain a default animator if you
//need to remember
Animator defaultAppearAnimator
= lt.getAnimator(APPEARING);
//create a new animator
ObjectAnimator someNewObjectAnimator;
//set it as your custom animator
lt.setAnimator(someNewObjectAnimator);
satya - Thursday, November 10, 2011 9:18:54 AM
Animator templates in layout transitions
Because the animator you supply to a layout transition applies to each view, they get internally cloned before being applied to each view.
satya - Thursday, November 10, 2011 9:20:30 AM
Key listening interfaces on an animator: Animator.AnimatorListener
Key listening interfaces on an animator: Animator.AnimatorListener
onAnimationCancel End Repeat Start
satya - Thursday, November 10, 2011 9:21:43 AM
layout transitions limitations
Read the above URL for more details, but if the views are moving in and out the clicks on views may not be predictable when they are in motion.
satya - Thursday, November 10, 2011 9:27:00 AM
Let me summarize everythign I have learned so far with an example
I wills start with a picture of what I am trying to animate and using what aspects of property animations
satya - Thursday, November 10, 2011 9:30:15 AM
In this demo I have used
An object animator to fade out and fade in individually
An object animator to fade out and fade in sequentially
Use an object animator builder to tie multiple animations together
in a relationship.
Use XML to load an animation from a resource file
Use Property Values Holder to animate multiple values
Use view property animator to optimize view animation
Use a type evaluator to move an object in 2 dimensions
Use key frames for checkered progress
satya - Thursday, November 10, 2011 9:44:28 AM
Let me start with the layotu file first
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_st_animation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="toggleAnimation"
android:text="Fade Out: Animator" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="sequentialAnimation"
android:text="FadeOut/FadeIn: Sequential" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="testAnimationBuilder"
android:text="FadeOut/FadeIn: Builder" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="sequentialAnimationXML"
android:text="FadeOut/FadeIn XML" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="testPropertiesHolder"
android:text="PVHolder" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="testViewAnimator"
android:text="ViewAnimator" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="testTypeEvaluator"
android:text="Type Evaluator" />
<Button
android:id="@+id/btn_st_animation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="testKeyFrames"
android:text="Key Frames" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/tv_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/blue"
android:textColor="@color/white"
android:text="@string/hello" />
</LinearLayout>
</LinearLayout>
satya - Thursday, November 10, 2011 9:46:03 AM
Couple of words about this layout
There are just a series of buttons that are tied to functions.
The text view is ensconced in a second linear layout because this will allow me to set the "x" and "y" values with respect to this layouts position that excludes the buttons. Otherwise the "x" and "y" values will be that of the bigger parent.
satya - Thursday, November 10, 2011 9:47:53 AM
Here is the code for each of the functions
public class TestPropertyAnimationActivity extends Activity
{
private static String tag = "My activity";
private TextView m_tv = null;
private MyAnimatableView m_atv = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gatherControls();
}
private void gatherControls()
{
m_tv = (TextView)this.findViewById(R.id.tv_id);
m_atv = new MyAnimatableView(m_tv);
}
public void toggleAnimation(View btnView)
{
Button tButton = (Button)btnView;
if (m_tv.getAlpha() != 0)
{
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
fadeOut.setDuration(5000);
fadeOut.start();
tButton.setText("Fade In");
}
else
{
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
fadeIn.setDuration(5000);
fadeIn.start();
tButton.setText("Fade out");
}
}
public void sequentialAnimation(View bView)
{
m_tv.setAlpha(1f);
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
AnimatorSet as = new AnimatorSet();
as.playSequentially(fadeOut,fadeIn);
as.setDuration(5000); //5 secs
as.start();
}
public void sequentialAnimationXML(View bView)
{
m_tv.setAlpha(1f);
AnimatorSet set = (AnimatorSet)
AnimatorInflater.loadAnimator(this,
R.animator.fadein);
set.setTarget(m_tv);
set.start();
}
public void testAnimationBuilder(View v)
{
m_tv.setAlpha(1f);
ObjectAnimator fadeOut =
ObjectAnimator.ofFloat(m_tv, "alpha", 0f);
ObjectAnimator fadeIn =
ObjectAnimator.ofFloat(m_tv, "alpha", 1f);
AnimatorSet as = new AnimatorSet();
as.play(fadeOut).before(fadeIn);
as.setDuration(2000); //2 secs
as.start();
}
public void testPropertiesHolder(View v)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
m_tv.setX(w);
m_tv.setY(h);
//Go to 50 on x
PropertyValuesHolder pvhX =
PropertyValuesHolder.ofFloat("x", x);
//Go to 100 on y
PropertyValuesHolder pvhY =
PropertyValuesHolder.ofFloat("y", y);
ObjectAnimator oa
= ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhX, pvhY);
oa.setDuration(5000); //2 secs
oa.setInterpolator(
new AccelerateDecelerateInterpolator());
oa.start();
}
public void testViewAnimator(View v)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
m_tv.setX(w);
m_tv.setY(h);
ViewGroup layout = (ViewGroup)m_tv.getParent();
layout.setClipChildren(true);
//Go to 50 on x
ViewPropertyAnimator vpa = m_tv.animate();
vpa.x(x);
vpa.y(y);
vpa.setDuration(5000); //2 secs
vpa.setInterpolator(
new AccelerateDecelerateInterpolator());
//vpa.start();
}
public void testTypeEvaluator(View v)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
ObjectAnimator tea =
ObjectAnimator.ofObject(m_atv
,"point"
,new MyPointEvaluator()
,new PointF(w,h)
,new PointF(x,y));
tea.setDuration(5000);
tea.start();
}
public void testKeyFrames(View v)
{
m_tv.setAlpha(1f);
float h = m_tv.getHeight();
float w = m_tv.getWidth();
float x = m_tv.getX();
float y = m_tv.getY();
//Start frame : 0.2
//alpha: 0.8
Keyframe kf0 = Keyframe.ofFloat(0.2f, 0.8f);
//Middle frame: 0.5
//alpha: 0.2
Keyframe kf1 = Keyframe.ofFloat(.5f, 0.2f);
//end frame: 0.8
//alpha: 0.8
Keyframe kf2 = Keyframe.ofFloat(0.8f, 0.8f);
PropertyValuesHolder pvhAlpha =
PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);
PropertyValuesHolder pvhX =
PropertyValuesHolder.ofFloat("x", w, x);
//end frame
ObjectAnimator anim =
ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhAlpha,pvhX);
anim.setDuration(5000);
anim.start();
}
}
satya - Thursday, November 10, 2011 9:48:47 AM
For the type evaluator animation you will need two other files
For the type evaluator animation you will need two other files
satya - Thursday, November 10, 2011 9:49:20 AM
Type evaluator
public class MyPointEvaluator
implements TypeEvaluator<PointF>
{
public PointF evaluate(float fraction,
PointF startValue,
PointF endValue)
{
PointF startPoint = (PointF) startValue;
PointF endPoint = (PointF) endValue;
return new PointF(
startPoint.x + fraction * (endPoint.x - startPoint.x),
startPoint.y + fraction * (endPoint.y - startPoint.y));
}
}
satya - Thursday, November 10, 2011 9:49:57 AM
Using the type evaluator to animate a view
public class MyAnimatableView
{
PointF curPoint = null;
View m_v = null;
public MyAnimatableView(View v)
{
curPoint = new PointF(v.getX(),v.getY());
m_v = v;
}
public PointF getCurPointF()
{
return curPoint;
}
public void setPoint(PointF p)
{
curPoint = p;
m_v.setX(p.x);
m_v.setY(p.y);
}
}
satya - Thursday, November 10, 2011 10:25:18 AM
I forgot to include the animation xml file: /res/animator/fadein.xml
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="2000" />
<objectAnimator
android:interpolator="@android:interpolator/accelerate_cubic"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="2000" />
</set>
Although I called it fadein.xml, it actually does fade out first followed by fadein.
satya - 7/27/2014 4:50:29 PM
default value for ValueAnimator setFrameDelay
default value for ValueAnimator setFrameDelay
satya - 7/27/2014 4:52:02 PM
It states here that it is 10 ms, from the guide
satya - 7/27/2014 5:14:40 PM
lifetime of valueanimator object in android
lifetime of valueanimator object in android
satya - 7/27/2014 5:18:57 PM
when is a valueanimator garbage collected?
when is a valueanimator garbage collected?