
Animating view and object properties
The property animation system provides a way for us to animate properties of any object, such as its position or opacity. It is also able to animate properties of custom types.
How to do it...
The ValueAnimator
type lets us animate values of some type for the duration of an animation by specifying set values to animate through. Let's take a look at the following steps:
- We obtain a
ValueAnimator
type by calling one of its factory methods, such asOfInt
,OfFloat
, orOfObject
. The instance is then used to tween a value from one value to another:ValueAnimator animator = ValueAnimator.OfInt(1, 1000); animator.SetDuration(5000); animator.SetInterpolator(new BounceInterpolator()); animator.Start();
- We can also use the
ObjectAnimator
property to tween a property value from one value to another, in this case theAlpha
property:ObjectAnimator animator = ObjectAnimator.OfFloat( myButton, "alpha", 1.0f, 0.0f, 1.0f); animator.SetDuration(5000); animator.SetInterpolator(new BounceInterpolator()); animator.Start();
- If we want to create a custom object to animate, we have to add the
[Export]
attributes and inherit fromJava.Lang.Object
:public class MyType : Java.Lang.Object { int myValue; public int MyValue { [Export("getMyValue")] get { return myValue; } [Export("setMyValue")] set { myValue = value; } } }
- To animate custom properties, we use the camel case name of the property:
ObjectAnimator animator = ObjectAnimator.OfInt( myObject, "myValue", 0, 100);
We can extend the value animator with a custom type converter so that we can tween types that are unknown to Android. Let's take a look at the following steps:
- We implement the
ITypeEvaluator
interface, which has a singleEvaluate()
method:public class StringEvaluator : Java.Lang.Object, ITypeEvaluator { public Java.Lang.Object Evaluate( float fraction, Java.Lang.Object startValue, Java.Lang.Object endValue) { int level = (int)(fraction * 10); return string.Format ("Level {0}", level); } }
- And then we pass an instance of the type converter to the
ValueAnimator
instance:ValueAnimator animator = ValueAnimator.OfObject( new StringEvaluator(), 1, 1000); animator.SetDuration(5000); animator.SetInterpolator(new LinearInterpolator()); animator.Start();
There is also the ability to create animation sequences in XML and use those instead of creating it in code. Let's take a look at the following steps:
- The animator resource XML is stored in the
values
resource folder:<?xml version="1.0" encoding="UTF-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:propertyName="alpha" android:duration="2500" android:valueTo="0.0" /> <objectAnimator android:propertyName="alpha" android:duration="2500" android:valueTo="1.0" /> </set>
- Like views and menus, we inflate the animator by its resource ID:
Animator animator = AnimatorInflater.LoadAnimator( this, Resource.Animator.property); animator.SetTarget(myButton); animator.Start();
There are several events that we can subscribe to in order to be notified about important events during the animation. Let's take a look at the following steps:
- Some events are general, such as start and stop:
animator.AnimationStart += delegate { }; animator.AnimationEnd += delegate { };
- And there is the event that fires for every frame for the
ValueAnimator
type:valueAnimator.Update += (sender, e) => { Java.Lang.Object value = e.Animation.AnimatedValue; float fraction = e.Animation.AnimatedFraction; };
How it works...
The property animation system is a robust framework that allows us to animate almost anything. We can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property's value over a specified length of time.
The ValueAnimator
class lets us animate values of some type for the duration of an animation by specifying set values to animate through. We obtain a ValueAnimator
class by calling one of its factory methods, such as OfInt
, OfFloat
, or OfObject
.
ObjectAnimator
is a subclass of the ValueAnimator
class, with the ability to animate a named property of a target object. In order for an object to be animated, the object must inherit from the Java.Lang.Object
type.
This object must have getter()
and setter()
functions in the underlying Java. This is usually not a problem for Android objects as they will have these methods. For our new C# objects, we have to make sure that we tell the runtime what methods to generate. We can create a property and annotate getter
and setter
with the [Export]
attribute, passing the name that it should generate in the Java.
TypeEvaluator
is an object with a single method, Evaluate()
, that allows us to return an appropriate value based on the current point of the animation. This method receives a fraction
parameter, which is the current, interpolated fraction from the interpolator. This fraction is then used to calculate the actual value of the animation from the start and end values.
Animations have various events that we can subscribe to, such as the general animation lifecycle events, and the actual frame update events. The general events, such as AnimationStart
, AnimationEnd
, and AnimationRepeat
, can be used to perform actions when the state of the animation changes. The Update
event is very powerful and is used especially by the ValueAnimator
class as it fires each time there is a change in the animation frame. We can use this event to obtain the current animation position.
The property animation system also lets us declare property animations with XML instead of doing it programmatically. By defining our animations in XML, we can easily reuse our animations in multiple activities and more easily edit the animation sequence.
There's more...
Just like with type evaluators, we can also create custom interpolators. We do this by implementing IInterpolator
and the GetInterpolation()
method. As this is an object that will be passed to the Java API. It also needs to inherit from Java.Lang.Object
.
See also
- Animating fragment navigation
- Animating views on the UI