Xamarin.Forms Responsive Layout from Device Rotation

Intro

This is a brain dump on implementing a responsive layout based on a device being in Portrait or Landscape mode.

In summary, I used a ContentView’s ControlTemplate to host a layout that depends on a device being in Portrait or Landscape mode. In addition, I then overrode the OnSizeAllocated method on the ContentPage.

XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XForms"
             x:Class="XForms.RegistrationPage1">

    <ContentPage.Resources>
        <ResourceDictionary>
            <ControlTemplate x:Key="PortraitTemplate">
                <StackLayout>
                    <StackLayout VerticalOptions="CenterAndExpand">
                        <Entry Style="{StaticResource RegistrationEntry}" Text="{Binding Email}"    Placeholder="email"  />
                        <Entry Style="{StaticResource RegistrationEntry}" Text="{Binding Password}" Placeholder="password" IsPassword="True" Margin="0,15,0,0"  />
                    </StackLayout>

                    <Button Style="{StaticResource RegistrationButton}" Text="Next" FontAttributes="Bold" FontSize="Small" VerticalOptions="Fill" />
                </StackLayout>
            </ControlTemplate>

            <ControlTemplate x:Key="LandscapeTemplate">
                <Label Text="Landscape" />
            </ControlTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentView ControlTemplate="{StaticResource PortraitTemplate}" />

</ContentPage>

Code Behind

Override OnSizeAllocated method of a ContentPage and compare page width to height:

    public partial class RegistrationPage1 : ContentPage
	{
		public RegistrationPage1() => InitializeComponent();

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);

            ControlTemplate = GetTemplate(width, height);
        }

        ControlTemplate GetTemplate(double width, double height) =>
            (height > width) ? TemplateFrom("PortraitTemplate") : TemplateFrom("LandscapeTemplate");

        ControlTemplate TemplateFrom(string templateName) =>
            Resources[templateName] as ControlTemplate;
    }

Conclusion

Brain dump completed.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: