Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
.NET MAUI Cookbook

You're reading from   .NET MAUI Cookbook Build a full-featured app swiftly with MVVM, CRUD, AI, authentication, real-time updates, and more

Arrow left icon
Product type Paperback
Published in Dec 2024
Publisher Packt
ISBN-13 9781835461129
Length 384 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Alexander Russkov Alexander Russkov
Author Profile Icon Alexander Russkov
Alexander Russkov
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Chapter 1: Crafting the Page Layout FREE CHAPTER 2. Chapter 2: Mastering the MVVM Design Pattern 3. Chapter 3: Advanced XAML and UI Techniques 4. Chapter 4: Connecting to a Database and Implementing CRUD Operations 5. Chapter 5: Authentication and Authorization 6. Chapter 6: Real-Life Scenarios: AI, SignalR, and More 7. Chapter 7: Understanding Platform-Specific APIs and Custom Handlers 8. Chapter 8: Optimizing Performance 9. Index 10. Other Books You May Enjoy

Implementing device-specific layouts

Desktop and mobile devices have fundamental differences in the user experience. Here are just a few examples:

  • A small versus a large screen
  • A mouse versus a touchscreen
  • A physical versus a virtual keyboard
  • A single window versus multiple windows

There are even more differences, and all of them affect the UI – you can rarely craft a screen that will be convenient for both mobile and desktop devices without explicit adaptive logic.

While .NET MAUI gives you the power to use a single code base for multiple device types, it won’t automatically adapt your layout to a specific device. However, the OnIdiom and OnPlatform markup extensions will help you implement local customization, or even replace the entire view, based on the device type or operating system. We will use both the OnIdiom and OnPlatform extensions in this recipe to see how they differ from each other.

Getting ready

To follow the steps described in this recipe, we just need to create a blank .NET MAUI application. The default template includes sample code in the MainPage.xaml and MainPage.xaml.cs files, but you can remove it and leave only a blank ContentPage in XAML and a constructor with the InitializeComponent method in CS. When copying code snippets with namespaces, don’t forget to replace them with the namespaces in your project.

The code for this recipe is available at https://github.com/PacktPublishing/.NET-MAUI-Cookbook/tree/main/Chapter01/c1-DeviceSpecificLayout.

How to do it…

Let’s use OnIdiom to specify a single property, specify multiple properties, and replace the entire view. Each of these techniques may be the most suitable, based on your scenario. After that, we will use OnPlatform to show a button on Android and hide it on iOS:

  1. Use the OnIdiom markup extension to set a local property value based on the device type (desktop, phone, tablet, TV, or watch). To adjust the layout using OnIdiom, define a grid with two rows and set the first row’s height using OnIdiom, as follows:

    MainPage.xaml

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition
                Height="{OnIdiom Desktop=200, Phone=*}"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border BackgroundColor="Coral"/>
        <Border Grid.Row="1" BackgroundColor="DarkRed"/>
    </Grid>

    As you may have noticed, we used an expanded RowDefinition syntax here to adjust each RowDefinition height separately (instead of RowDefinitions="200, *"). Run the project on a desktop and phone to see the result.

    Figure 1.5 – Idiom-specific settings

    Figure 1.5 – Idiom-specific settings

  1. To adjust a bunch of properties using one OnIdiom condition, define a style for each device type:
    <ContentPage.Resources>
        <Style TargetType="Grid" x:Key="winUiBorderStyle">
            <Setter Property="Padding" Value="20"/>
            <Setter Property="Margin" Value="20"/>
        </Style>
        <Style TargetType="Grid"
               x:Key="androidBorderStyle">
            <Setter Property="Padding"
                    Value="10,0,10,10"/>
            <Setter Property="Margin" Value="10"/>
        </Style>
    </ContentPage.Resources>
    <Border Style="{OnIdiom Desktop={StaticResource
            winUiBorderStyle}, Phone={StaticResource
            androidBorderStyle}}" BackgroundColor="Coral">
        <Border BackgroundColor="DarkRed"/>
    </Border>

    Run the project to see the result.

  2. To switch the entire view based on the device type, define separate views for each device and set the ContentPage.Content property using an expanded OnIdiom tag. If you haven’t created ContentView before, right-click on the project, and then select Add | New Item | ContentView. Name one view PhoneView and the other DesktopView:

    PhoneView.xaml (for Android/iOS)

    <ContentView
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="c1_DeviceSpecificLayout.PhoneView">
        <Border>
            <Label Text="Phone View"/>
        </Border>
    </ContentView>

    DesktopView (for Windows/macOS/Linux)

    <ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="c1_DeviceSpecificLayout.DesktopView">
        <Border>
            <Label Text="Desktop View"/>
        </Border>
    </ContentView>

    MainPage.xaml

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:local="clr-namespace: c1_DeviceSpecificLayout"
        x:Class="c1_DeviceSpecificLayout.MainPage">
        <ContentPage.Content>
            <OnIdiom x:TypeArguments="View">
                <OnIdiom.Phone>
                    <local:PhoneView />
                </OnIdiom.Phone>
                <OnIdiom.Desktop>
                    <local:DesktopView />
                </OnIdiom.Desktop>
            </OnIdiom>
        </ContentPage.Content>
    </ContentPage>

    Note that the TypeArguments attribute of OnIdiom should be set to View. Don’t forget to add a namespace definition to MainPage to be able to reference PhoneView and DesktopView.

    This technique is useful when there are significant differences between the mobile and desktop views and customizing separate controls is problematic.

  1. Use the OnPlatform markup extension to specify properties that depend on an operating system:
    <Button IsVisible="{OnPlatform Android=True,
            iOS=False}"/>

    This code sets Button.IsVisible to True on Android and to False on iOS devices, showing or hiding the button, respectively, based on the operating system. You can also specify different values for other platforms supported in MAUI – MacCatalyst, Tizen, and WinUI.

How it works…

Under the hood, OnIdiom checks the current device information using the DeviceInfo class and returns a value you specified in XAML:

Here is a simplified code snippet illustrating the idea:

public class OnIdiomExtension : IMarkupExtension {
    public object Default { get; set; }
    public object Phone { get; set; }
    public object Desktop { get; set; }
    //...
    public object ProvideValue(IServiceProvider serviceProvider) {
        //...
        if (DeviceInfo.Idiom == DeviceIdiom.Phone)
            return Phone ?? Default;
        if (DeviceInfo.Idiom == DeviceIdiom.Desktop)
            return Desktop ?? Default;
        //...
        return Default;
}

The OnPlatform extension works in the same way, but it uses the DeviceInfo.Platform property to get the currently running platform and return the value you specified in XAML.

There’s more…

If you need to implement more complex logic, you can specify device-specific settings in C#. For example, the following code sets a grid’s height based on the idiom value:

public MainPage() {
    InitializeComponent();
    if (DeviceInfo.Current.Idiom == DeviceIdiom.Desktop) {
        grid1.Height = CalculateDesktopHeight();
    }
    else if (DeviceInfo.Current.Idiom == DeviceIdiom.Phone)
    {
        grid1.Height = CalculateMobileHeight();
    }
}

The CalculateDesktopHeight and CalculateMobileHeight methods are supposed to contain custom calculation logic that cannot be easily implemented in XAML.

You can implement similar customization logic based on the DeviceInfo.Current.Platform property for each operating system. Alternatively, you can use conditional compilation and platform-specific code, as we will demonstrate in Chapter 7, Understanding Platform-Specific APIs and Custom Handlers.

You have been reading a chapter from
.NET MAUI Cookbook
Published in: Dec 2024
Publisher: Packt
ISBN-13: 9781835461129
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image