Well thought out animations can help your applications come to life through having better user experience and a sense of joy. This Xamarin.Forms UI Challenge illustrates how simple it can be to add compelling animations into your applications.
This is a great looking design called Unzone created by Rick Waalders. The star of this design is the flip animations, which do a great job of adding personality and being functional without becoming annoying.
The key elements we will focus on in this challenge are:
- Creating a modal dialog style interaction by fading the background when a cell is clicked
- Flying in the cancel button from the bottom of the page
- Open and Close animations for the buttons on the modal dialog
- Flipping the dialog when the Delete button is clicked
- Remove a cell with a nice little bounce effect.
Basic Page Layout
If you have checked out any of my other Xamarin.Forms UI Challenges, you are probably aware that I really enjoy using a
Grid as the main layout container for pages. However, this challenge requires very exacting positioning of elements so this time we opt for an
AbsoluteLayout to make sure we can get the positioning correct.
AbsoluteLayout is great for very specific positioning and is pretty efficient because it doesn’t consume a bunch of layout cycles. However, it is pretty complex and you don’t get some of the dynamic goodness of managed layouts (like
Do check out the documentation, which is top notch.
The list of cells is a
StackLayout with a
BindableLayout.ItemsSource to create a cell for each row of data.
You may notice that there are two types of custom cells, PersonTimeCell and a YouTimeCell. To keep things simple, these two cells are defined in their own classes.
This is the main cell that is used for the different time zones in the list. If you have a look at it, it’s a pretty simple layout which consists of a
Grid of three columns and a
StackLayout for the middle column.
There is really just one of these cells and it is designed to show your current time zone.
What brings this all together is the
DataTemplateSelector which allows us to specify which cell is used for a particular row of data. If we look at the data that is backing the cells there is a field called
TimeInfoType which specifies if it’s a Person or a You type of cell.
It all kind of makes sense when you have a look at our
And then we apply the DataTemplateSelector in our XAML via the
Okay, so that’s probably enough about how the collection of timezones is constructed. Let’s get into the fun stuff.
Popup with faded background
The design has a nice effect when the user selects one of the person cells where it darkens everything except the selected cell.
In reality, it’s very simple to achieve. The basics of it are:
Fade in a whole screen dark overlay over the content. This stops the user from selecting things in the background. You can set it’s
BackgroundColorto have some transparency baked in too (
#CC000000) which means the user can still see the content behind it.
Have an additional
PersonCellthat sits over the overlay which is positioned exactly where the selected cell is located. Now, set the
BindingContextof the fake cell to the binding context of the selected cell so that it shows the same data.
Animating the Close Button
Another really nice effect is the Close button that pops in from the bottom when a cell is selected.
This is really just a case of positioning the close button relative to the selected cell and then doing some animations to adjust it’s Position, Rotation and Opacity.
The entering and exiting animations vary slightly which is why it passes in an parameter into the AnimateCloseButton method.
Really the only interesting part of this is that it uses the animation extension methods which Xamarin.Forms provides, namely
TranslateTo. These are awaitable methods, but if you don’t await them, you can kick of multiple animations that run at the same time.
You might notice that we always position the close image beneath the fake cell, which is mostly fine for the purpose of this UI Challenge, but in reality you and your designer would probably have to think about this a little more. What happens when when the selected cell is at the bottom of the screen?
Folding down the buttons
Even though the folding down buttons are a little gratuitous they add a bit of personality to the app. The key behind this effect is to adjust the rotation of elements so that they appear to fold down.
Rotation can be done on the X, Y and Z axis
An important thing to know about rotations is that they happen around the
AnchorY of the element. Think of the the
Anchor as the rotation point.
The default value for
AnchorX is .5 which means the middle (but not important for what we are doing). The important thing is to have the
AnchorY to “0” which means that the rotation is going to happen around the TOP of the element.
Step 1: Set the starting state
You might notice that in the code above we are doing an
await on the
OpenDropDown method. This is basically saying wait (without blocking the main UI thread) until the previous dropdown has finished. If we didn’t have that, then they would all animate in at the same time and we would lose of staggered effect.
Step 2: Animate that puppy
When animating in with the
OpenDropDown method we start by setting it’s initial Visibility, RotationX and Opacity.
The fold down animation is actually a Fade and a RotationX. In the below code you can see that the
FadeTo is NOT awaited which means it will happen at the same time as the
RotateXTo happens. It’s a small detail, but what I have learnt about design is that it’s all about the small details.
Closing the drop down is effectively the reverse. Start it fading, wait for it to rotate, and then set it invisible.
Flipping the dialog
Creating a flip effect consists of having a
- Rotating the
fromview around the middle of it’s Y axis until you are looking at it’s edge. (effectively invisible)
- Swapping to the
toview (also rotated)
- Rotate the
toview around it’s middle so that it comes into view.
It’s simpler than it sounds:
As a bonus you might notice there is a nice little
SpringOut easing to give it a little bounce.
Bouncing up the items
The final effect that is worth mentioning in this UI Challenge is the bounce animation for deleting an item from the list. I’ll admit this is a little hacky but seems to work quite nicely (just don’t try it with thousands of elements)
The basic idea is:
- Close down the overlays.
- Iterate through all the items after the selected element
- Create an animation to move it to location of the previous element with a bounce easing
- Wait for all those animations to finish
- Remove the selected element
BTW, the reason for the FadeOut before removing the element is really just in case you are deleting the last element in the list.
Okay, so that’s the key elements in this UI Challenge. It was definitely a fun UI to put together, and not too difficult when you break it apart into it’s elements. Mostly it’s smoke and mirrors but it doesn’t provide a great looking UI.
Get the code
All the code is available open source on my github.
Watch me code it
I actually did this UI Challenge live over Twitch, so if you want to watch hours of me coding this up then check out these recordings.
If you want to catch me doing other live coding things follow me on Twitch. It’s a great platform where we can chat as we build software, ask questions, submit code). Follow me at https://www.twitch.tv/kymphillpotts and come join in the fun!
If you can’t make it to the Twitch streams, then I also upload the videos to my YouTube Channel
I hope these posts are useful for you, feel free to leave me a comment below or reach out to me via Twitter.
Until next time, Happy Coding