Pizza is like the entire food pyramid. And This Xamarin UI Challenge, like our friend the pizza, has lots of delicious ingredients including animations, transitions, custom buttons, fonts and a sprinkle of SkiaSharp. Nom Nom.
The key elements we will focus on in this challenge are:
Flying pizzas around the screen using an animation state helper
Custom stepper button with flip up labels
“Chomp Button” when a pizza is added to the cart
Basic Page Layout
The main page of the application uses a Grid as its main container which is fine for most of the elements. However, in order to control over the position of the flying pizza another key element is using an AbsoluteLayout which allows us to have precise control of the pizza.
In this design there are ingredients flying all over the screen. To simplify this we use an AnimationStateEngine class to control the positions of the pizza for various states.
There are five states which are represented in an enumeration:
We use a custom AnimationStateEngine to control elements for each of the states. There is quite a bit of code to setup the various elements, but as an example for the pizza we setup positions and rotation for the pizza for each state.
Then to do the animation it’s just a matter of activating a particular state and the AnimationStateEngine will handle the translations for us.
As I said, there is quite a bit more in the code and you should definitely checkout the code if you are interested in the inner workings of it. But hopefully that gives you enough of a clue to see the benefits of this sort of approach.
The design calls for a fancy stepper control that rotates the quantity up and down.
The main layout of this is a Grid. The first column just has the the Label. So not particularly interesting.
The second column is where the magic happens. To create the buttons and outline for the stepper button, we just use a frame and a couple of buttons with appropriate Border and CornerRadius settings. But interestingly here we don’t enclose the buttons inside the frame, rather we use the magic of Grid to have the elements overlapping each other.
The Ferris Label Control
Now for the rotating label. We put this into a custom control because it’s used in multiple places in the design so we can reuse it. It’s called a FerrisLabel which is kind of a play on the words that it’s like a carousel but vertical.
It’s actually quite simple. It uses two labels and a couple bindable properties that respond to when the text changes to kick off an animation.
Behind the scenes, we have an AnimationOffset property which controls which way the animations should go (up or down, or even diagonal if you want). Also a BindableProperty for the Text, which kicks off the animations when it detects a change.
So from there it’s just a matter of doing the animations:
So back in our calling code all we need to do is update the property and the animations get triggered from the bindable property.
Chomping Pizza Button
This is my favorite piece of animation. It’s a very playful way of adding the pizza to the shopping cart.
The key to this animation is having a hidden FlyingPizza image, which is exactly over top of the normal pizza image. Once the Pizza needs to fly, we make it it visible, animate its LayoutBounds so that it flies down to the bottom right of the PlaceOrderButton. Then at the same time, adjust the bounds of the Button to allow a space for the pizza. There is also a little bit of animation to rotate the pizza as it’s flying and as it lands on the button.
Not terribly complicated code, but it’s a really nice effect. To move it back out of the button when the quantity decreases there is another method called RegurgitatePizza which pretty much does the same thing but in reverse.
As with a lot of complex designs there are often things which require some custom graphics. In this case the ruler for the pizza size is rendered using SkiaSharp.
And finally there is the button which appears on the ruler, which is only interesting in so much that it has a constant animation showing the direction of the arrow. You can’t achieve this with the normal Animation extension methods but with a custom animation you can do this very easily by just setting the repeat to true:
Okay, so that’s the key elements in this UI Challenge. It was a lot of fun to put together and the final result is pretty delicious.
Get the code
There are some complexities which I haven’t gone into in this blog post, but I’ve covered most of the interesting ingredients. 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. 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.