Responsive Layouts in .NET MAUI: Master device orientation
.NET MAUI enable us to write platform and device-factor independent apps, which makes it neccessary to adapt dynamically to the users screen size and form. In this blog post you learn how to make your XAML layouts adapt to different device orientations, using a similar syntax to OnIdiom and OnPlatform that you might already be familiar with.
BlogResponsive Layouts in .NET MAUI: Master device orientation
This post is part of the MAUI UI July 2023 community series of blog posts and videos, hosted by Matt Goldman. Be sure to check out the other posts in this series!
Let's have a look at how we can use the MarkupExtension OnOrientation:
Layouts of mobile apps should be responsive and adapt to various screen sizes and different orientations, to provide an engaging user experience. While we are accustomed to using devices in portrait orientation where there is more vertical screen space than horizontal, there are still cases where it makes sense to switch to landscape orientation, even on phones.
Making a .NET MAUI app switch between Portrait and Landscape seamlessly can be a challenge. The first step in the right direction can be to avoid fixed sizes where possible and let the controls scale automatically. However, oftentimes the app ends up with lots of blank space in either of the orientations, as you can see in the example below.
By providing different values to properties of layouts like ColumnDefinitions from Grid we can make better use of the additional horizontal screen space.
This can easily be done by using a custom MarkupExtension so that it can be used directly in XAML like this:
Why TypeConverter is specified here will be explained below.
If you have a project in Xamarin or .NET MAUI, we can help you save time.
Before proceeding on your own, take a look at our services. Our team of experienced developers is enthusiastic about discussing your project and helping you finish with an excellent standard.
In contrast to other MarkupExtensions like OnPlatform and OnIdiom, where the factor deciding which value to use is determined at startup, OnOrientation works differently, since the orientation changes at runtime. That means OnOrientation needs to provide a value that changes at runtime. This can be achieved by returning a Binding in ProvideValue(IServiceProvider serviceProvider), with a Source that implements INotifyPropertyChanged, in this case an object of OnOrientationSource. OnOrientationExtension uses the DeviceDisplay.MainDisplayInfoChanged event to publish a message via the WeakReferenceMessenger.
OnOrientationSource provides the current value via the Value property. It's getter evaluates the current orientation and returns the appropriate value. When the orientation changes, it receives the OrientationChangedMessage and fires the PropertyChanged event for Value resulting in an update in the view.
You may have noticed that OnOrientationExtension also defines the property TypeConverter. Unfortunately, when using a MarkupExtension the TypeConverter mechanism does not kick in, normally resulting in a type mismatch. That's why TypeConverter can be used to specify which kind of TypeConverter to use for converting the string value from the OnOrientation expression, providing a simple workaround to that limitation. To find out which TypeConverter should be applied developers can check out the TypeConverterAttribute the BindableProperty is annotated with as in this example.
Using OnOrientation
Install CommunityToolkit.Maui into the project
Add UseMauiCommunityToolkit() to MauiProgram.cs when configuring the MauiAppBuilder
Add both classes, OnOrientationExtension.cs and OnOrientationSource.cs, to the .NET MAUI project
Add the namespace alias to the XAML file
Use OnOrientation either inline as MarkupExtension in attribute syntax, or via property element syntax
Since the values you provide in a MarkupExtension must be of a primitive type like int or string, and type conversion using TypeConverters does not kick in, sometimes you may need to use x:Static to refer to static variables or Enum values.
When a complex value is needed and no matching TypeConverter exists, then you can also use property element syntax to specify the different values. Although one can argue that this is way too verbose for practical use.
However, this syntax could also be used to switch out entire views:
<ContentView>
<ContentView.Content>
<ext:OnOrientation>
<Label Text="This text is visible in Default" />
<ext:OnOrientation.Landscape>
<Label Text="This text is visible in Landscape" />
</ext:OnOrientation.Landscape>
</ext:OnOrientation>
</ContentView.Content>
</ContentView>
Gained some interest in our work?
We assume that you have gained some interest in our work since you have made it this far. Please feel free to give us your feedback or discuss a project of yours. We would be pleased to hear from you.
OnOrientation is based on the orientation provided by DeviceDisplay.MainDisplayInfo.Orientation, therefore it does not work properly on desktop platforms. Also, a Binding expression can not be used as one of the values.
Conclusion: Adapting layouts in .NET MAUI for device orientation
Adapting the layout with OnOrientationExtension can be quite comfortable and flexible. But keep in mind that there are other ways to handle orientation changes too, so make sure to check out these articles:
As Head of Technology, I support my team and our clients with the latest technologies and trends in Android and iOS development. Our projects benefit from my Xamarin and .NET MAUI experience, as well as my penchant for clean code, attractive UIs and intuitive UX. You are welcome to book me for a workshop.
This post is a continuation of the Hackathon topic post, where the technical implementation of voice commands in .NET MAUI is revealed, as well as the challenges the development team faced and how they successfully solved them.
As mobile app developer, we constantly have the need to exchange information between the app and the backend. In most cases, a RESTful-API is the solution. But what if a constant flow of data exchange in both directions is required? In this post we will take a look at MQTT and how to create your own simple chat app in .NET MAUI.
With the end of support for Xamarin approaching in May 2024, developers are busy migrating existing Xamarin.Forms projects to .NET MAUI as its successor. So are we, of course. In this article, I'll show 7 steps we've always had to take during the transition to make your upgrade .NET MAUI easier.