画面やウィンドウのサイズに関係なくアプリの見栄えをよくする (Windows 10 by 10)

※本ブログは Building Apps for Windows "Make your app look great on any size screen or window (10 by 10)" の抄訳です。

Windows 10 のユニバーサル Windows プラットフォームを使用すると、さまざまなデバイスでアプリを実行できるようになり、プラットフォームのコントロールでサポートされる異なるサイズの画面やウィンドウに合わせて自動的にスケーリングできるようになります。Windows 10 by 10 開発シリーズでは、これから 3 週に渡って、このようなデバイス ファミリでアプリのユーザー操作をサポートする方法、アプリを実行するデバイスにアプリが応答および適応する方法、複雑なコードを記述する手間を省くためにプラットフォームで提供しているものについて説明します。

今回の記事では、さまざまなデバイス ファミリ向けにユーザー インターフェイスを最適化できるレスポンシブ手法について説明します。次回は、アプリでサポートできる複数の自然入力の種類について説明した後、アプリが特定のデバイス機能に適応する方法について詳しく説明します。

1_deviceFamily

デバイス ファミリの概要

コントロール、API、コードについて説明する前に、デバイス ファミリについて簡単に説明します。詳しい説明は「ユニバーサル Windows プラットフォーム (UWP) アプリのガイド」で確認できますが、端的にいうと、デバイスファミリとは、上記に示すような特定のフォーム ファクターを持つデバイスのグループです。アプリを設計するときには、アプリを実行するデバイス ファミリについて考慮することが重要になります。

Windows 10は、新しい種類のデバイスで利用できるようになったため、アプリについて再検討し、アプリで実現できる新しいエクスペリエンスについて考えてみてください。この記事ですべてのデバイス ファミリを網羅することはできませんが、新しいデバイス ファミリでアプリを実行するときにアプリの応答方法を決定する際には、これらのアイデアや概念を応用できます。

帰ってきたウィンドウ

Windows でアプリを実行する方法における最大の変化は、よくご存じのとおり、ウィンドウでアプリを実行することです。Windows 8 と Windows 8.1 では、アプリを全画面で実行したり、最大 4 個のアプリを同時に表示することができましたが、Windows 10 では、ユーザーが自由にアプリを整列、サイズ変更、配置できます。この変化により、ユーザーは望みどおり、柔軟にアプリを実行できるようになりますが、このようなユーザー操作を実現するには、開発者側で何らかの作業が必要になります。Windows 10 における XAML の改良により、アプリにレスポンシブ手法を実装する多数の方法が導入されました。そのため、画面やウィンドウのサイズに関係なく、アプリの見栄えが良くなります。以下で、レスポンシブ手法を実装する 3 つの方法について説明します。

1. VisualStateManager

Windows 10 の VisualStateManager クラスは、XAML ベースのアプリにレスポンシブ設計を実装する 2 つのメカニズムによって拡張されました。新しい VisualState.StateTriggers (英語) API と VisualState.Setters (英語) API を使用すると、特定の条件に対応する表示状態を定義できます。VisualState の StateTrigger として MinWindowHeight プロパティや MinWindowWidth プロパティを設定した組み込みの AdaptiveTrigger (英語) を使用すると、アプリのウィンドウの高さと幅に基づいて表示状態を変更できるようになります。Windows.UI.Xaml.StateTriggerBase (英語) を拡張すると、デバイス ファミリや入力の種類に応じてトリガーするといった独自のトリガーを作成することもできます。次の例をご覧ください。

 <Page>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState>
                    <VisualState.StateTriggers>
                    <!-- ウィンドウの有効なピクセル幅が =720 の場合に
                         >VisualState はトリガーされます。 -->
                        <AdaptiveTrigger MinWindowWidth="720" />
                    </VisualState.StateTriggers>
 
                    <VisualState.Setters>
                        <Setter Target="myPanel.Orientation"
                                Value="Horizontal" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <StackPanel x:Name="myPanel" Orientation="Vertical">
            <TextBlock Text="This is a block of text. It is text block 1. "
                       Style="{ThemeResource BodyTextBlockStyle}"/>
            <TextBlock Text="This is a block of text. It is text block 2. "
                       Style="{ThemeResource BodyTextBlockStyle}"/>
            <TextBlock Text="This is a block of text. It is text block 3. "
                       Style="{ThemeResource BodyTextBlockStyle}"/>
        </StackPanel>
    </Grid>
</Page>

この例では、既定の状態で、ページには積み重なって表示される 3 つの TextBlock 要素が表示されます。この VisualStateManager には、MinWindowWidth に 720 を設定した AdaptiveTrigger が含まれているため、ウィンドウの有効なピクセル幅が 720 以下の場合には StackPanel の向きが横に変更されます。この設定により、ユーザーがウィンドウ サイズを変更したり、スマートフォンやタブレット デバイスの向きを縦向きから横向きに変更したときには、新たに得られた横方向の画面領域を簡単に活用できます。width プロパティと height プロパティの両方を設定すると、アプリが両方の条件を同時に満たした場合にのみ、トリガーが発動することに注意してください。ぜひ GitHub の状態トリガーのサンプル (英語) を確認して、多数のカスタマイズしたトリガーを含む、トリガーの使用シナリオをご覧ください。

2. RelativePanel

上記の例では、StateTrigger を使用して、StackPanel の Orientation プロパティを変更しました。XAML の多くのコンテナ要素を利用すると、StateTriggers を使用してさまざまな方法でユーザーインターフェイスを操作できますが、要素を相対的に配置する複雑なレスポンシブ UI を簡単に作成する方法は用意されていません。そこで誕生したのが、新しい RelativePanel (英語) プロパティです。RelativePanel を使用して要素間の空間的な関係を指定することにより、要素を配置できます。次に例を示します。

 <RelativePanel BorderBrush="Gray" BorderThickness="10">
    <Rectangle x:Name="RedRect" Fill="Red" MinHeight="100" MinWidth="100"/>
    <Rectangle x:Name="BlueRect" Fill="Blue" MinHeight="100" MinWidth="100"
               RelativePanel.RightOf="RedRect" />
    <!-- 緑と黄色の長方形では幅が設定されていません。
         長方形の幅は RelativePanel のプロパティで決定されています。 -->
    <Rectangle x:Name="GreenRect" Fill="Green"
               MinHeight="100" Margin="0,5,0,0"
               RelativePanel.Below="RedRect"
               RelativePanel.AlignLeftWith="RedRect"
               RelativePanel.AlignRightWith="BlueRect"/>
    <Rectangle Fill="Yellow" MinHeight="100"
               RelativePanel.Below="GreenRect"
               RelativePanel.AlignLeftWith="BlueRect"
               RelativePanel.AlignRightWithPanel="True"/>
</RelativePanel>

上記の XAML コードは、以下のようにレンダリングされます。

2_rendering

ご覧のように、RelativePanel の添付プロパティを使用することで、青、緑、黄色の長方形は、相対的にレンダリングされています。つまり、複数の AdaptiveTrigger を RelativePanel と併用すると、利用可能な画面領域に基づいて要素を移動できるレスポンシブなユーザー インターフェイスを簡単に作成できます。添付プロパティで使用する構文には、かっこを追加することに注意してください。

 <VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState>
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="720" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="GreenRect.(RelativePanel.RightOf)"
                        Value="BlueRect" />
            </VisualState.Setters>
        </VisualState>
...

RelativePanel プロパティを使用する他のシナリオについては、GitHub のレスポンシブ手法のサンプル (英語) をご覧ください。

3. SplitView

アプリのページ コンテンツだけでなく、ナビゲーション要素もアプリのウィンドウ サイズの変更に対応しなければならない場合があります。Windows 10 で導入された新しい SplitView (英語) コントロールは、通常、アプリのウィンドウサイズに応じて異なる動作を設定できる上位レベルのナビゲーションエクスペリエンスを作成するために使用します。これは SplitView の一般的な使用例ですが、この使用例に限定されるわけではないことに注意してください。SplitView は、Pane および Content という 2 つの個別の領域に分かれています。

3_splitView

コントロールに用意されている多数のプロパティを使用して、レンダリングを操作できます。

DisplayMode (英語) (Overlay、Inline、CompactOverlay、CompactInline) は、Content 領域に対する Pane のレンダリング方法を指定します。次の例は、それぞれの DisplayMode がアプリのレンダリングに影響を与えるようすを示しています。

4_displayMode

PanePlacement (英語) プロパティでは、Pane を Content 領域の左 (既定の設定) または右に表示するかを指定します。OpenPaneLength (英語) プロパティでは、完全に拡張したときの Pane の幅を指定します (既定の設定では、有効なピクセル幅は 320 です)。

SplitView コントロールには、アプリでよく見かける “ハンバーガー” メニューなどの、ユーザーが Pane の状態を切り替えられるようにする組み込みのユーザーインターフェイス要素は用意されていません。Pane の状態を切り替えるユーザー インターフェイス要素は、アプリで定義して、SplitView の IsPaneOpen (英語) プロパティを切り替えて期待する動作を実現するコードを提供する必要があります。

GitHub の XAML ナビゲーション メニューのサンプル (英語) を確認して、SplitView が提供するすべての機能をご覧ください。

戻るボタンを押して元の場所に戻る

Windows Phone 対応アプリの開発経験がある場合は、すべてのデバイスに、ユーザーがアプリでの遷移をたどれるようにするハードウェアまたはソフトウェアの戻るボタンが用意されている状況に慣れているでしょう。ただし、Windows 8 や Windows 8.1 用のアプリを作成するときには、戻る操作用に独自の UI を作成する必要がありました。開発者の皆さんが Windows 10 アプリで複数のデバイス ファミリをターゲットにする作業を簡略化できるよう、すべてのユーザーに一貫した戻る操作を提供する方法をご用意しました。この機能により、これまでアプリで用意していた一部のユーザー インターフェイスの領域が解放されます。

SystemNavigationManager (英語) の AppViewBackButtonVisibility  (英語) プロパティを使用して、ハードウェアまたはソフトウェアの戻るボタンが用意されていない PC などのデバイス ファミリでシステム用の戻るボタンを表示することもできます。戻るボタンを表示するには、以下のように、現在のビューの SystemNavigationManager を取得して、戻るボタンが表示されるように設定します。

 SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;

5_store

SystemNavigationManager では、ユーザーが戻る操作を目的としてシステムに用意されているボタン、ジェスチャー、またはボイスコマンドを起動した場合に発動される BackRequested (英語) イベントも公開しています。つまり、この単一のイベントを操作することで、すべてのデバイス ファミリでアプリの戻る操作を同じように処理できます。

タブレットか PC かを判断する

最後に重要なことですが、個人的に気に入っている、Windows 10 の Continuum (英語) について説明します。Continuum を使用すると、開発者が望む処理とその処理方法に合わせて、Windows 10 がエクスペリエンスを調整します。現在市場に出回っている 2-in-1 型 Windows PC をユーザーが利用している場合、アプリに Continuum を実装することで、ユーザーはタッチ操作またはマウス操作とキーボード操作を使用して生産性を最適化できるようになります。UIViewSettings (英語) の UserInteractionMode (英語) プロパティを使用すると、ユーザーがビューと対話するためにタッチ操作またはマウス操作とキーボード操作のどちらを使用しているかを判断できます。

 UIViewSettings.GetForCurrentView().UserInteractionMode;
// UserInteractionMode.Mouse または UserInteractionMode.Touch を返します

対話モードを検出したら、余白を増やす/減らす、複雑な機能を表示/非表示にするなど、アプリのユーザーインターフェイスを最適化できます。新しい StateTriggers と UserInteractionMode を組み合わせて独自のカスタム Continuum StateTrigger を作成する方法については、Lee McPherson が執筆した優れた TechNet 記事 (英語) をご覧ください。

今週は、さまざまなデバイス ファミリでアプリがユーザーに応答できるようにしましょう

Windows 10 が提供するレスポンシブ手法について解説した今回の記事が、これらの機能をアプリに実装して、ユーザーが任意のデバイスでアプリの実行を楽しめるようにする方法についてインスピレーションを得る一助となればさいわいです。レスポンシブなアプリに変更するためにできることについて、以下に最後のヒントを紹介します。

  1. アプリに AppViewBackButtonVisibility プロパティと BackRequested イベントを実装して、すべてのデバイス ファミリで一貫した戻る操作の動作を提供する
  2. アプリのウィンドウ サイズを変更するユーザーに対応して、アプリのエクスペリエンスを最適化するうえで、StateTriggers をどのように活用できるかを考える
  3. 新しい SplitView コントロールと RelativePanel コントロールを使用して、一貫したユーザー エクスペリエンスを提供する

その後、DVLUP の課題「適応するレスポンシブな UI」(英語) を確認して、多大なる努力に対する報酬としてポイントと XP を獲得してください。Windows 10 by 10 開発シリーズについて詳しくお知りになりたい場合は、コンテンツの投稿予定を掲載している最初のブログ記事 をご覧ください。

いつものように、以下に、レスポンシブ Windows 10 アプリの作成について学習できる追加リソースを紹介します。ぜひ、@WindowsDev 宛てにハッシュタグ #Win10x10 を付けて、この新機能の使用計画を英語でお知らせください。