アイキャッチ画像

.NET MAUIでレスポンシブデザインを実装する方法について

.NET MAUIでレスポンシブデザインの実装方法を紹介していきます。

.NET MAUIではデバイスに合わせたデザイン変更ができますが、画面サイズによってデザイン変更を行いたい時もあります。当記事では、画面サイズに合わせてデザイン変更する方法を紹介していきます。

紹介環境

当記事は以下の環境で作成しています。

  • Visual Studio 2022
  • .Net 8

レスポンシブデザインとは?

レスポンシブデザインとは、画面サイズに合わせて最適化するデザインを指します。

本来はWebサイトで利用されるデザインになります。

PC・タブレット・スマートフォンごとに画面サイズが異なりますが、一つのHTMLで画面サイズに合わせたCSSを利用することでデザインを変更していきます。

.NET MAUIではXAMLを利用してデザインを変更していきます。

.NET MAUIでレスポンシブデザインを実現する方法

.NET MAUIでレスポンシブデザインを実現するためには「AdaptiveTrigger」を利用します。

「AdaptiveTrigger」について

「AdaptiveTrigger」は状態トリガーの一つで、トリガーはウィンドウの幅・高さになります。

ウィンドウの幅・高さの指定するプロパティは、以下のようになります。

  • ウィンドウの最小の幅:MinWindowWidth(double型)
  • ウィンドウの最小の高さ:MinWindowHeight(double型)

「ウィンドウの最小」の意味が分かりにくいので、次の例で説明していきます。次の例は「AdaptiveTrigger」を「Entry」に利用した例になります。

<Entry>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState Name="Small">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0"></AdaptiveTrigger>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="#FFF"></Setter>
                    </VisualState.Setters>
                </VisualState>
                <VisualState Name="Medium">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="500"></AdaptiveTrigger>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="#FF0"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </VisualStateManager.VisualStateGroups>
</Entry>

動作させたイメージが、以下のようになります。ウィンドウの幅が500未満の時には白色になり、500以上の時には黄色になります。

実際に表示してみたイメージ

つまり、「ウィンドウの最小」とはトリガーとなるウィンドウの最低サイズになります。

画面サイズに合わせて切り替わるメニューを作成してみる

画面サイズに合わせて切り替わるメニューを「AdaptiveTrigger」で作成してみます。切り替わるメニューには「AppShell.xaml」の「FlyoutBehavior」を利用します。

「AppShell.xaml」の「FlyoutBehavior」を以下のように切り替えていきます。

  • ウィンドウの幅(500未満):サイドメニューを非表示
  • ウィンドウの幅(500以上 1000未満):ハンバーガーメニューでサイドメニューの表示・非表示を切り替え
  • ウィンドウの幅(1000以上):サイドメニューを表示

実際に利用した例が以下のようになります。

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="MauiAppResponsiveDesign.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiAppResponsiveDesign"
    xmlns:pages="clr-namespace:MauiAppResponsiveDesign.Pages"
    Shell.FlyoutBehavior="Disabled"
    BackgroundColor="#512BD4"
    ForegroundColor="#FFFFFF"
    TitleColor="#FFFFFF"
    Title="MauiAppResponsiveDesign">

    <!-- 追加してみた例 -->
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState Name="Small">
                    <VisualState.StateTriggers>
                        <!-- ウィンドウの幅(500未満) -->
                        <AdaptiveTrigger MinWindowWidth="0"></AdaptiveTrigger>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!-- サイドメニューを非表示 -->
                        <Setter Property="FlyoutBehavior" Value="Disabled"></Setter>
                    </VisualState.Setters>
                </VisualState>

                <VisualState Name="Medium">
                    <VisualState.StateTriggers>
                        <!-- ウィンドウの幅(500以上 1000未満) -->
                        <AdaptiveTrigger MinWindowWidth="500"></AdaptiveTrigger>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!-- ハンバーガーメニューでサイドメニューの表示・非表示を切り替え -->
                        <Setter Property="FlyoutBehavior" Value="Flyout"></Setter>
                    </VisualState.Setters>
                </VisualState>

                <VisualState Name="Large">
                    <VisualState.StateTriggers>
                        <!-- ウィンドウの幅(1000以上) -->
                        <AdaptiveTrigger MinWindowWidth="1000"></AdaptiveTrigger>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!-- サイドメニューを表示 -->
                        <Setter Property="FlyoutBehavior" Value="Locked"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </VisualStateManager.VisualStateGroups>
    <!-- ここまで -->

    <ShellContent
        Title="SamplePage1"
        ContentTemplate="{DataTemplate pages:SamplePage1}"
        Route="SamplePage1" />
    <ShellContent
        Title="SamplePage2"
        ContentTemplate="{DataTemplate pages:SamplePage2}"
        Route="SamplePage2" />
</Shell>

動作イメージ(Windows)

Windowsで動作させたイメージは以下のようになります。

動作イメージ_Windows

動作イメージ(Android)

Androidで動作させたイメージは以下のようになります。Androidでは画面の向きを変更することで確認できます。

動作イメージ_Android

macOS・iOSでは動作しない

macOS・iOSで「AdaptiveTrigger」を利用すると起動時のみ反映され、リサイズしても反映されません。以下で紹介されていますが、不具合の可能性があるようです。

実際にiOSで動作させたイメージが以下のようになります。

以下は縦向きでアプリを起動させ横向きにした状態になります。「AdaptiveTrigger」がウィンドウの幅(500未満)の状態になっています。

iOSでAdaptiveTriggerがウィンドウの幅(500未満)になっている

次に横向きでアプリを起動させた状態が以下になります。「AdaptiveTrigger」がウィンドウの幅(500以上 1000未満)になっています。

iOSでAdaptiveTriggerがウィンドウの幅(500以上 1000未満)になっている

iOSで画面を固定する方法について

iOSでは起動時のみ「AdaptiveTrigger」が反映されます。そのため、ここではアプリの画面を固定する方法を紹介します。

手順① 「Info.plist」を選択します

まずは「Info.plist」を開きます。「Info.plist」を開くには「Platforms\iOS\Info.plist」を選択します。

「Info.plist」の開き方

手順② デバイスの向きを選択します

「アプリケーション」からデバイスの向きを選択します。

縦向きの場合は、以下のように「デバイスの向き」を縦のみ選択します。

デバイスの向き固定(縦)

横向きの場合は、以下のように「デバイスの向き」を横(左回転)・横(→回転)を選択します。

デバイスの向き固定(横)

おわりに

Windowsアプリとスマートフォンアプリでデザインの合わせる際にウィンドウサイズが問題になることが多くなると思います。「AdaptiveTrigger」は、その問題を解決するためにとても役に立つと思います。