Customize UI appearance based on the platform and device idiom
.NET Multi-platform App UI (.NET MAUI) apps can have their UI customized for specific platforms and devices. This enables your app to:
- Make the most effective use of space. If you design an app to look good on a mobile device, the app will still be usable on a desktop device but there will most likely be some wasted space. You can customize your app to display more content when the screen is above a certain size. For example, a shopping app might display one item at a time on a mobile device, but might show multiple items on a desktop device. In addition, by placing more content on screen you can reduce the amount of navigation that users need to perform.
- Take advantage of device capabilities. Certain devices are more likely to have certain capabilities. For example, mobile devices are more likely to have a location sensor and a camera, while desktop devices might not have either. Your app can detect which capabilities are available and enable controls that use them.
- Optimize for input. You can rearrange your UI elements to optimize for specific input types. For example, if you place navigation elements at the bottom of the app, they'll be easier for mobile users to access. But desktop users often expect to see navigation elements towards the top of the app.
When you optimize your app's UI for specific platforms and device idioms, you're creating a responsive UI. The primary approach to creating a responsive UI in .NET MAUI involves using the OnPlatform<T> and OnIdiom<T> classes. An alternative approach is to use the OnPlatform
and OnIdiom
XAML markup extensions. However, these markup extensions aren't trim safe. For more information about the markup extensions, see Customize UI appearance with markup extensions.
Note
There is a category of triggers, known as state triggers, that can be used to customize UI appearance in specific scenarios such as when the orientation of a device changes. For more information, see State trigger.
Customize UI appearance based on the platform
The OnPlatform<T> and On classes enable you to customize UI appearance on a per-platform basis:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,20,0,0" />
<On Platform="Android" Value="10,20,20,10" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
OnPlatform<T> is a generic class and so you need to specify the generic type argument, in this case, Thickness, which is the type of Padding
property. This is achieved with the x:TypeArguments
XAML attribute. The OnPlatform<T> class defines a Default property that can be set to a value that will be applied to all platforms:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" Default="20">
<On Platform="iOS" Value="0,20,0,0" />
<On Platform="Android" Value="10,20,20,10" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
In this example, the Padding
property is set to different values on iOS and Android, with the other platforms being set to the default value.
The OnPlatform<T> class also defines a Platforms property, which is an IList
of On objects. Each On object can set the Platform and Value property to define the Thickness value for a specific platform. In addition, the On.Platform property is of type IList<string>
, so you can include multiple comma-delimited platforms if the values are the same:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" Default="20">
<On Platform="iOS, Android" Value="10,20,20,10" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
Providing an incorrect Platform value won't result in an error. Instead, your XAML will execute without the platform-specific value being applied.
Note
If the Value
property of an On
object can't be represented by a single string, you can define property elements for it.
Customize UI appearance based on the device idiom
The OnIdiom<T> class enables you to customize UI appearance based on the idiom of the device the app is running on:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
<ContentPage.Margin>
<OnIdiom x:TypeArguments="Thickness">
<OnIdiom.Phone>0,20,0,0</OnIdiom.Phone>
<OnIdiom.Tablet>0,40,0,0</OnIdiom.Tablet>
<OnIdiom.Desktop>0,60,0,0</OnIdiom.Desktop>
</OnPlatform>
</ContentPage.Margin>
...
</ContentPage>
OnIdiom<T> is a generic class and so you need to specify the generic type argument, in this case, Thickness, which is the type of Margin
property. This is achieved with the x:TypeArguments
XAML attribute. The OnIdiom<T> class defines a Default property that can be set to a value that will be applied to all platforms:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
<ContentPage.Margin>
<OnIdiom x:TypeArguments="Thickness" Default="20">
<OnIdiom.Desktop>0,60,0,0</OnIdiom.Desktop>
</OnPlatform>
</ContentPage.Margin>
...
</ContentPage>
In this example, the Margin
property is set to a specific value on desktop idioms, with the other idioms being set to the default value.
Customize UI appearance with markup extensions
UI appearance can also be customized with the OnPlatform
and OnIdiom
markup extensions. However, these markup extensions aren't trim safe.
Customize UI appearance with a markup extension based on the platform
The OnPlatform
markup extension enables you to customize UI appearance on a per-platform basis. It provides the same functionality as the OnPlatform<T> and On classes, but with a more concise representation.
The OnPlatform
markup extension is supported by the OnPlatformExtension class, which defines the following properties:
Default
, of typeobject
, that you set to a default value to be applied to the properties that represent platforms.Android
, of typeobject
, that you set to a value to be applied on Android.iOS
, of typeobject
, that you set to a value to be applied on iOS.MacCatalyst
, of typeobject
, that you set to a value to be applied on Mac Catalyst.Tizen
, of typeobject
, that you set to a value to be applied on the Tizen platform.WinUI
, of typeobject
, that you set to a value to be applied on WinUI.Converter
, of type IValueConverter, that can be set to an IValueConverter implementation.ConverterParameter
, of typeobject
, that can be set to a value to pass to the IValueConverter implementation.
Note
The XAML parser allows the OnPlatformExtension class to be abbreviated as OnPlatform
.
The Default
property is the content property of OnPlatformExtension. Therefore, for XAML markup expressions expressed with curly braces, you can eliminate the Default=
part of the expression if it's the first argument. If the Default
property isn't set, it defaults to the BindableProperty.DefaultValue
property value, provided that the markup extension is targeting a BindableProperty.
Important
The XAML parser expects that values of the correct type will be provided to properties consuming the OnPlatform
markup extension. If type conversion is necessary, the OnPlatform
markup extension will attempt to perform it using the default converters provided by .NET MAUI. However, there are some type conversions that can't be performed by the default converters and in these cases the Converter
property should be set to an IValueConverter implementation.
The following XAML example shows how to use the OnPlatform
markup extension:
<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green}"
WidthRequest="{OnPlatform 250, iOS=200, Android=300}"
HeightRequest="{OnPlatform 250, iOS=200, Android=300}"
HorizontalOptions="Center" />
In this example, all three OnPlatform
expressions use the abbreviated version of the OnPlatformExtension class name. The three OnPlatform
markup extensions set the Color, WidthRequest, and HeightRequest properties of the BoxView to different values on iOS and Android. The markup extensions also provide default values for these properties on the platforms that aren't specified, while eliminating the Default=
part of the expression.
Warning
The OnPlatform
markup extension isn't trim safe and shouldn't be used with full trimming or NativeAOT. Instead, you should use the OnPlatform<T> class to customize UI appearance on a per-platform basis. For more information, see Customize UI appearance based on the platform, Trim a .NET MAUI app and Native AOT deployment.
Customize UI appearance with a markup extension based on the device idiom
The OnIdiom
markup extension enables you to customize UI appearance based on the idiom of the device the app is running on. It provides the same functionality as the OnIdiom<T> class, but with a more concise representation.
The OnIdiom
markup extension is supported by the OnIdiomExtension class, which defines the following properties:
Default
, of typeobject
, that you set to a default value to be applied to the properties that represent device idioms.Phone
, of typeobject
, that you set to a value to be applied on phones.Tablet
, of typeobject
, that you set to a value to be applied on tablets. This property isn't exclusive to Android and iOS platforms.Desktop
, of typeobject
, that you set to a value to be applied on desktop platforms. Note that some laptops may be classified using theTablet
property.TV
, of typeobject
, that you set to a value to be applied on TV platforms.Watch
, of typeobject
, that you set to a value to be applied on Watch platforms.Converter
, of type IValueConverter, that can be set to an IValueConverter implementation.ConverterParameter
, of typeobject
, that can be set to a value to pass to the IValueConverter implementation.
Note
The XAML parser allows the OnIdiomExtension class to be abbreviated as OnIdiom
.
The Default
property is the content property of OnIdiomExtension. Therefore, for XAML markup expressions expressed with curly braces, you can eliminate the Default=
part of the expression if it's the first argument.
Important
The XAML parser expects that values of the correct type will be provided to properties consuming the OnIdiom
markup extension. If type conversion is necessary, the OnIdiom
markup extension will attempt to perform it using the default converters provided by .NET MAUI. However, there are some type conversions that can't be performed by the default converters and in these cases the Converter
property should be set to an IValueConverter implementation.
The following XAML example shows how to use the OnIdiom
markup extension:
<BoxView Color="{OnIdiom Yellow, Phone=Red, Tablet=Green, Desktop=Blue}"
WidthRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HeightRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HorizontalOptions="Center" />
In this example, all three OnIdiom
expressions use the abbreviated version of the OnIdiomExtension class name. The three OnIdiom
markup extensions set the Color, WidthRequest, and HeightRequest properties of the BoxView to different values on the phone, tablet, and desktop idioms. The markup extensions also provide default values for these properties on the idioms that aren't specified, while eliminating the Default=
part of the expression.
Warning
The OnIdiom
markup extension isn't trim safe and shouldn't be used with full trimming or NativeAOT. Instead, you should use the OnIdiom<T> class to customize UI appearance based on the idiom of the device the app is running on. For more information, see Customize UI appearance based on the device idiom, Trim a .NET MAUI app and Native AOT deployment.