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 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
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 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
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.
Margin="14,172,14,0"is what brings the content down so that it doesn’t sit entirely at the top of the page.
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.
The next bit is the movie information and ratings inside the container. This is really just combination of
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.
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
TranslateToanimation 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
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,
Grids are your friends!
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