Coordinator Layout with Xamarin.Forms
In this article we’ll create a simple Xamarin Forms app that uses the Coordinator Layout. The app is inspired by a view from the Blinkist app and it will have similar animations for its title section and the buttons right below it.
The Coordinator Layout allows you to synchronise a top view and a bottom view by changing the top view based on the scrolling position of the bottom view.
Have a look at the gif below and notice how the title view is expanding and the label is increasing in size while scrolling down. Source.
Heads Up
In a production-ready app you’d use MVVM and have the content be provided by a viewmodel from a data source. Since the focus of this article is to use CoordinatorLayout, I decided not to muddle the waters by providing any code that’s not directly relevant.
To build the app you’ll need:
Visual Studio with the Mobile app workload or Rider.
Android Emulator or a real device.
Basic Xamarin.Forms knowledge.
A few spare minutes.
Let’s go
Create a new blank Xamarin.Forms application. I’m using Rider and for me that looks like this
Upgrade the preinstalled Xamarin.Forms library and add a reference to the CoordinatorLayout.XamarinForms NuGet package to all the projects.
Build and run the Android app, just to make sure everything is working as expected. In case you encounter some error, it should be easier to fix it now rather than later.
In the MainPage.xaml add an xml namespace for CoordinatorLayout.XamarinForms and add a CoordinatorLayout element. To see anything in your app add a Label to the CoordinatorLayout.TopView and another Label with overflowing text to the CoordinatorLayout.BottomView.
The CoordinatorLayout control has default values that allow you to expand the top view by dragging on the bottom view up and down.
Bottom View
Let’s finish up the bottom view, since that’s the easiest. Just give the Label the following values for Padding and BackgroundColor
BackgroundColor="SteelBlue" Padding="10,30,10,10"
Action View
The Action View is an optional view that sits on the border between the Top View and to Bottom View.
We’ll use that to create the Read and Listen buttons from the first screenshot.
Since the ActionView just “hovers” on the aforementioned border region, it partially overlaps the Top and Bottom Views. This means that it can’t really compute its required height and we have to tell it how tall it should be.
The CoordinatorLayout allows us to express the Action View’s height proportionally to its own height using the property ProportionalActionViewContainerHeight. For this sample app we’ll set it to ”0.1".
By default, the Action View is hidden when the Top View is collapsed. For this app we don’t want that, so we’ll turn off that behaviour by setting AutohideActionView=”False”.
To display those rounded buttons with a separator in between I’m using a Grid with three columns, containing a Button, a BoxView and another Button respectively. For the rounded corners I’m using a Frame with a CornerRadius of 20.
Action View containing two buttons with rounded corners.
At this point the app should look like this
It would be really fancy to change the width and the corner radius of the buttons depending on the expansion progress of the Top View. The CoordinatorLayout has an event called ExpansionEventHandler that contains the expansion progress. The progress is reported as a value between 0.0 (top view is completely shrunk) and 1.0 (top view is completely expanded).
To leverage that event we’ll need to give the Frame element a name, like “ActionFrame” and to add a callback method for the ExpansionEventHandler.
In the callback method all we have to do is vary the Frame’s corner radius and margin between a minimum and a maximum value.
Adjusting the Frame’s corner radius and the margin based on the expansion progress.
At this point the Action View smoothly changes from a button bar to a sticky button header when scrolling up.
Top View
The top view will start in the expanded state and will show a background image, the author name, a title and a partial underline. When shrunk, those elements will fade out and a new smaller title will fade in.
To achieve this, we’ll set InitialExpansionState=”Expanded” on the CoordinatorLayout and add all the necessary elements to the Top View.
Notice that the smaller title (called SecondaryTitle) starts out with its Opacity=”0.0”.
Using the same callback method for the expansion progress that we used before, we can implement the described behaviour of the Top View.
Since the expansion progress is 0.0 when the Top View is shrunk and 1.0 when it is fully expanded, we can use that value as it is for the opacity of the background image and the title.
For the secondary title, we’ll use a formula that fades the Label in when the Top View is almost completely shrunk and fades it out otherwise.
Take a moment to drag up and down on the CoordinatorLayout and observe the nice animations. While you expand the Top View, its content slowly fades into view and the Action View moves downward while at the same time morphing from a rectangular button bar into a rounded button area.
The last step is to add the transparent buttons to the left and right of the top view. There are multiple ways of creating those buttons and for this sample app we’ll leverage Xamarin’s support for custom fonts and the FontImageSource class.
First download the Material Design Icons from here and extract the zip file. Add the .ttf font file to your shared project and set its Build action to EmbeddedResource.
Build action for the .ttf file should be EmbeddedResource.
A couple of versions ago Xamarin.Forms got really good support for custom fonts, such that all you need to do is add this line to your App.xaml.cs
[assembly: ExportFont("materialdesignicons-webfont.ttf", Alias = "MaterialDesign")]
ExportFont attribute in the App.xaml.cs class.
We are now ready to add the buttons. The easiest way is to nest the entire CoordinatorLayout in a Grid element and then to add the buttons on top of the CoordinatorLayout.
The buttons are defined below the CoordinatorLayout, but still inside the Grid.
Conclusion
You should now have an app that looks like this
The snapping behaviour is built into CoordinatorLayout but you can tweak it or even turn it off. Here’s an explanation of all the adjustable properties https://github.com/mariusmuntean/CoordinatorLayout.Forms#property-reference
Disclaimer
I am the creator of CoordinatorLayout.XamarinForms and I’ve recently released version 1.3.0, which improves touch input support for the Bottom View. Give it a try and let me know what you built with it.
The source code of the library contains a full-blown sample app that highlights everything CoordinatorLayout.XamarinForms can do.
While you’re there, have a look at my other open source projects. I publish all my projects under the MIT license and you’re free to do anything with my code. Have fun!
Top comments (0)