There are many more extension methods:
ScaleTo,
RotateTo,
LayoutTo and
TranslateTo, all of them work the same way. You need to provide the final value and the duration, then you can provide an Easing function. You can take a detailed look at them
here.
There is also another method in the
ViewExtensions class, called
CancelAnimation, that get a View as a parameter and allows you to cancel an initiated animation on the target View.
You can also create combined animations, so you show more complex effects on the screen. All methods for animations are async, so you can play with await or not await them to make async or sync animations in an easy way:
- FadeTo, with a duration of 750 milliseconds, without await.
- ScaleTo, with a duration of 1500 milliseconds, with await. This one is launched at the same time of the FadeTo, since it is not awaited.
- ScaleTo, with a duration of 500 milliseconds, with await. Since the previous ScaleTo is awaited, this one is launched when the previous one finished.
This way gives you a big control over how the animations are launched and allows you to combine many little animations to do awesome things.
Xamarin
Now we will see how to make the same animation in Xamarin. Since Xamarin asks you to create a native view for each platform, you will need to know how to make animations in iOS, Android and Windows.
Windows
In Windows and Windows Phone you can use the power of XAML to create awesome animations. In the first place let's start creating the same Label, a TextBlock in XAML:
- <Grid>
- <TextBlock x:Name="TextHello"
- Text="{Binding Hello}"
- VerticalAlignment="Center"
- HorizontalAlignment="Center"
- Foreground="Blue"
- Opacity="0"
- RenderTransformOrigin=".5,.5">
- <TextBlock.RenderTransform>
- <CompositeTransform ScaleX="1" ScaleY="1"/>
- </TextBlock.RenderTransform>
- </TextBlock>
- </Grid>
In XAML you need to add a CompositeTransform instance to your element if you want to animate the scale or rotation of it. Now you can create a Storyboard to animate the Opacity and Scale of the TextBlock:
- <views:MvxWindowsPage.Resources>
- <Storyboard x:Key="TextBlockAnimation" Duration="0:0:1.5">
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="Opacity">
- <LinearDoubleKeyFrame KeyTime="0:0:0.750" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)">
- <LinearDoubleKeyFrame KeyTime="0:0:1.0" Value="2"/>
- <LinearDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
- <LinearDoubleKeyFrame KeyTime="0:0:1.0" Value="2"/>
- <LinearDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </views:MvxWindowsPage.Resources>
And finally you only need to launch the animation, using a behavior or by code in the OnNavigatedTo method:
- protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
-
- var animation = (Storyboard)this.Resources["TextBlockAnimation"];
- animation.Begin();
- }
That's all, you have the same animation you made before in Xamarin.Forms, now in Windows and Windows Phone. Now is Android's turn.
Android
In Android you need to use AXML files to create the animation. Let's start creating the TextView to show in your page:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:local="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:id="@+id/TextHello"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="40dp"
- android:textColor="#00F"
- local:MvxBind="Text Hello" />
- </LinearLayout>
Now it is time to start working with an animation set. Start creating a new AXML file in the Drawable folder inside the Resources folder. Call it TextAnimation, as in the following example:
- <?xml version="1.0" encoding="utf-8"?>
- <set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false">
- <alpha android:interpolator="@android:anim/linear_interpolator"
- android:toAlpha="1"
- android:startOffset="0"
- android:duration="750"/>
- <scale android:interpolator="@android:anim/linear_interpolator"
- android:scaleGravity="center_vertical"
- android:toXScale="2"
- android:toYScale="2"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="0"
- android:duration="1000"/>
- <scale android:interpolator="@android:anim/linear_interpolator"
- android:scaleGravity="center_vertical"
- android:toXScale="1"
- android:toYScale="1"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="1000"
- android:duration="500"/>
- </set>
To execute multiple animations over one object in Android, you need to create a SET. It behaves in a way like the XAML Storyboards. Then you can use various AXML objects like Alpha, Scale and Rotate to animate the object. All the animations here are all launched together, so you need to use the StartOffset property if you want to make any of them launch after another. And voilá! our animation is done and working!
iOS
Last but not least, iOS. Since the iOS interface is created in C# you can take advantage of it to easily create awesome animations. As with the previous platforms, start creating the screen contents in the override ViewDidLoad method:
- public override void ViewDidLoad()
- {
- View = new UIView { BackgroundColor = UIColor.White };
- base.ViewDidLoad();
-
-
- if (RespondsToSelector(new Selector("edgesForExtendedLayout")))
- {
- EdgesForExtendedLayout = UIRectEdge.None;
- }
-
- var label = new UILabel(new CGRect(10, 100, 300, 60));
- label.Alpha = 0f;
- label.TextColor = UIColor.Blue;
- Add(label);
-
- var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
- set.Bind(label).To(vm => vm.Hello);
- set.Apply();
- }
Now you can use the Animate method of the UIView class to define and create your animation as in the following:
- private void CreateLabelAnimation(UILabel label)
- {
- UIView.Animate(0.75, 0, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Alpha = 1f;
- }, null);
- UIView.Animate(1, 0, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Transform = CGAffineTransform.MakeScale(2f, 2f);
- }, null);
- UIView.Animate(0.5, 1, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Transform = CGAffineTransform.MakeScale(1f, 1f);
- }, null);
- }
Animate the method has the following five parameters:
- Animation duration, in seconds.
- Animation offset in seconds, before start.
- Type of easing/transition function to use from UIViewAnimationOptions enum.
- An action (void method without parameters) to execute. Here is where you can use the element transformations to animate them.
- An action (void method without parameters) to execute when the animation has finished.
The animation code above is so simple, it is nearly self-explanatory. The first animation simply increases the Alpha to 1 at 750 milliseconds with a linear easing function.
For the scale, you can use the
MakeScale method of the
CGAffineTransform object to create a transform for the element.
Finally
To end, you can grab the source code for all these samples in my GitHub account
here. I hope this little article and sample code help you make awesome animations in your apps.