Xamain.Forms contain many Animations API that is accessible in the shared code. Most animation sequences can be leveraged in the shared code reducing the need to implement any platform specific code to handle animations. Scaling animations can add a lot of context to your sequences that provide context to your animations. This Scaling article is part of a greater Xamarin Animations series of blogs.
Scaling
Control scaling can be used across many different types of controls. A common implementation would be resizing an image depending on a behavior.
- Splash Screen
- Making images larger on selection
- etc.
Let’s build a custom control that zooms in and out when the user taps on the logo.
- Create new Xamarin.Forms project for iOS and Android
- Validate it runs on both platforms
Hello World with Icon
Create a simple Hello World page that has an icon on it, feel free to use the default Xamagon Icon. In our example I went over to Material Icons and downloaded the close (X) icon.
Image Control
1
<Image source="clear" />
Our final XAML
is slightly more verbose to include a label with instructions
MainPage.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamarinAnimations.Scaling"
x:Class="XamarinAnimations.Scaling.MainPage">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label Text="Tap the X to scale" />
<Image Source="clear" /
</StackLayout>
</ContentPage>
Building Blocks
We now should have a very simple page that displays a message to tap the icon and an image appearing on the screen.
Configure Tap Event
With the basic layout all working corectly we can configure tap event and start working in the code behind. Update the MainPage.xaml
to include a GestureRecgonizer
. You will also need to give the Image
control a name using x:Name
. This allows us to access it in the code behind.
Gesture Recgonizer
1
2
3
4
5
<Image x:Name="Icon" Source="clear">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
</Image.GestureRecognizers>
</Image>
MainPage.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamarinAnimations.Scaling"
x:Class="XamarinAnimations.Scaling.MainPage">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label Text="Tap the X to scale" />
<Image x:Name="Icon" Source="clear">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</ContentPage>
Animation Code
Open up the MainPage.xaml.cs
and stub out the event we created in the previous step. Your code should look something like this:
MainPage.xaml.cs (stubbed)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace XamarinAnimations.Scaling
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
}
}
}
Create Scale Variable
Create a simple scale
variable to store the current scale, which will be used to perform calculations when the event is fired.
1
2
3
4
5
6
7
8
9
10
11
public partial class MainPage : ContentPage
{
private double _scale = 0;
public MainPage()
{
InitializeComponent();
_scale = Icon.Scale;
}
// .. omitted code
}
Update Event Signature for Async
Forcing the app to run the animations to completion by adding the async
keyword to the method signature.
1
2
3
4
private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
}
Invoke Animation Commands
Now everything is in place, invoke the ScaleTo
command specifying the wait time. Then invoke ScaleTo
back to the original size that we saved earlier.
1
2
3
4
5
private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
await Icon.ScaleTo(_scale * 1.5, 500);
await Icon.ScaleTo(_scale, 500);
}
The second parameter of 500
is the elapsed time for the animation to take in milliseconds.
Complete Code Behind (MainPage.xaml.cs)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace XamarinAnimations.Scaling
{
public partial class MainPage : ContentPage
{
private double _scale = 0;
public MainPage()
{
InitializeComponent();
_scale = Icon.Scale;
}
private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
await Icon.ScaleTo(_scale * 1.5, 500);
await Icon.ScaleTo(_scale, 500);
}
}
}
Result
The resulting animation is a quick scale up and scale down on click. Your resulting animation should look something like this
-Happy Coding