Xamarin.Forms UI Challenges - RottenUI
This UI Challenge is all about composing overlapping elements in Xamarin.Forms. Overlapping elements is one of the subtle elements that can enhance a design and make it pop.
The Design
This is a great looking design called Rottentomatoes App Concept created by Ghani Pradita. Even though the design has two screens in it, the focus of this chanllenge was the details page.
The key elements we will focus on in this challenge are:
- Overlapping elements
- Custom rendering of shadows
- Tabbed bottom content
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. At the surface the Grid
seems to be quite limited in terms of functionality, but the Grid
provides a couple of great benefits:
- Responsive design
- Overlapping elements
The Grid
makes a perfect layout for this sort of design. The Grid
occupies the page, and is divided into two rows. The first row is for the background header of 200 units, whilst the second row occupies the rest of the page and is where the main content goes.
Okay, so let’s break this down into the various sections.
The Header
The header for the page has a few overlapped components. First we have the background image, over that we have a play button and a white overlay.
This is nice and simple to implement with a Grid
because we can just put the elements into the same cell of the Grid
to have them overlay. In this situation, order is important because the order that you put the elements in your xaml
file indicates the z-order. Sometimes this can be a little confusing because the elements you want to be in front will actually go down the bottom of your xaml
.
Probably the only interesting point here is the white gradient down the bottom of the header. There are a few different ways you could implement this. First, and probably the technically best solution is to use SkiaSharp to render a transparent to white gradient. In this case though, I have just implemented this with a very simple .png
file with a gradient and overlayed it over the image. Sometimes simple just works.
The Movie Details
Okay onto the more interesting part, which is the movie details.
This get’s a little bit funky because we have numerous elements overlapping within the details section as well as the whole thing overlapping the header. The trick here is that the details of the page actually sit in Row 0 of the table but span across 2 rows. (hence it sits above and overlapping the header).
There are a couple of things to note in here.
- The
Margin="14,172,14,0"
is what brings the content down so that it doesn’t sit entirely at the top of the page. - The
IsClippedToBounds="True"
is what allows the FRESH text to be clipped to the grid.
Okay, let’s break it down even further into the elements:
Movie Information Container
The main container for the movie information is a white BoxView
and a green Boxview
for the button with a combination of CornerRadius
to make it look pretty.
The hardest part was the shadow for the button. If you look at it carefully, you’ll notice that it’s actually smaller than the button and has a big blur. I had to do this with SkiaSharp - because that’s where I go when I need to render funky things ;-)
Fortunately, Skia is amazing and allows us to easily do things like create a shadow effect.
Movie Information
The next bit is the movie information and ratings inside the container. This is really just combination of Grid
and StackLayout
.
For the FRESH text unfortunately I couldn’t see a way of getting that to work with a label because the font spacing and size is very specific, so instead I used an image like this:
and then translated it using a negative right margin (to make it wider than the cell) and then translated it to the left so that it would go under the poster.
The Poster
And that just leaves us with the poster. I used the most excellent PancakeView
to get the rounded corners. But what is interesting about this is that because it’s got to go over all the other information it is the very last thing that appears in the xaml
even though it’s at the top.
The Tabbed Bottom Content
Alright, so that just leaves us with the bottom tabs. In Xamarin.Forms there is a TabbedPage
, but not a tabbed view. There are a number of ones available in the Open Source community, but none that would deo exactly what I was after. But, it is super easy to create your own.
In our case we implemented this in it’s own ContentView
so as not to bloat the size of the MainPage
. It’s implemented in a file called DetailsSection.xaml
. The layout for the tab headers is just a Grid
with 5 columns. Each column has a Label
which is shown on the Tab header.
We also have the little orange element that moves with the selection. This is just a a couple of BoxView
elements (which we will animate later)
To be fair, there is a tiny bit of structure for the control by having a couple of collections for the headers and contents. We load these up in the constructor.
For each of the headers labels we have TapGestureRecognizer
that all call the same method. That method works out which index we have selected and then calls a method to do the tab switching.
Just to cover off the key things that happen inside ShowSelection
method above:
- We use a
TranslateTo
animation to change the position of the orange indicator to the bounds of the selected header - We use the application resources to change the style of the TabHeader labels
- We fade out the existing tab content
- We fade in the new tab content
Summary
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. Just remember people, Grid
s are your friends!
Components Used
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. And as a special bit of fun James Montemagno jumped in on the stream towards the end and shows a trick or two. Thanks James!
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
❤ Kym