クイック スタート: さまざまなウィンドウ サイズに合わせたアプリの設計

この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、 「最新のドキュメント」をご覧ください]

どのウィンドウ サイズでも適切に表示され、正しく機能するアプリを設計する場合、既定の全画面の横長のレイアウトを補完する追加のレイアウトを作成するかどうかを選ぶ必要があります。 既定の最小幅の 500 ピクセルではなく 320 ピクセルの最小幅をサポートし、アプリの高さが幅よりも大きくなったときに縦長レイアウトに切り替えるようにアプリを設計できます。これらは省略可能な設計の選択肢です。

この機能の実際の使い方については「アプリの機能の概要」シリーズの次のトピックをご覧ください: Windows ストア アプリ UI の概要

目標: この記事を読むと、アプリの最小幅を 500 ピクセルから 320 ピクセルに変更する方法や、狭い幅でもアプリが適切に表示され、正しく機能するように設計を変更する方法を理解できます。また、アプリの高さが幅よりも大きくなったときには常に、横方向にパンするアプリが縦長レイアウトに変化するように設計する方法も理解できます。

必要条件

JavaScript を使った初めての Windows ストア アプリの作成

レイアウトとスケーリングの UX ガイドライン

サンプル: 高さが幅よりも大きいウィンドウのレイアウト

この記事では、縦長で幅の狭いレイアウトが、高さが幅よりも大きいウィンドウのレイアウトのサンプルでどのように実装されているかを説明することによって、このようなレイアウト用の追加の設計オプションを紹介します。このサンプルは、Microsoft Visual Studio のグリッド アプリケーション テンプレートに基づいています。

グリッド アプリケーション テンプレートには、次の 4 つのページがあります。

  • default (default.html): アプリの起動後、単に groupedItems ページを読み込みます。
  • groupedItems (pages\groupItems\groupedItems.html): ユーザーは、グループと項目を表示できます。グループ ラベルを選んで グループの詳細ページ (groupDetail) に移動したり、項目を選んで 項目のページ全体表示 (itemDetail) に移動したりできます。
  • groupDetail (pages\groupDetail\groupDetail.html): ユーザーは、グループの詳細と項目を表示できます。項目を選ぶと項目のページ全体表示 (itemDetail) に移動できます。
  • itemDetail (pages\itemDetail\itemDetail.html): 項目のページ全体表示です。

この記事では、既定のレイアウトを各ページに使います。groupDetail ページと groupedItems ページに対応する JavaScript のコード ビハインドに必要な変更のみを取り上げます。

ここで重要となるコーディング手法は、ページの offsetWidth プロパティと offsetHeight プロパティの変化を調べることです。ユーザーがページの幅やデバイスの向きを変更した結果、幅と高さが特定の値に達した場合、ページのレイアウトとそのコントロールの動作が変化します。

Visual Studio で試すには、JavaScript Windows ストアの "グリッド アプリケーション" プロジェクトを新規作成し、以降の手順に従ってください。

最小幅の定義

既定では、Windows ストア アプリの最小幅は 500 ピクセルです。アプリの高さは常に画面の高さで表示されます。アプリの最小画面の高さは 768 ピクセルです。

アプリが狭い幅で適切に動作する場合や、マルチタスクがアプリにとって重要なシナリオであり、常に他のアプリと同じ画面上に表示しておく必要がある場合は、最小幅を 500 ピクセルではなく 320 ピクセルに変更できます。これにより、ユーザーは、全画面表示から 320 ピクセルの幅まであらゆるサイズに、アプリのサイズを滑らかに変更できます。

package.appxmanifest マニフェスト ファイルでアプリの最小幅を変更します。そのために、Visual Studio で、次の手順を実行します。

  1. package.appxmanifest マニフェスト ファイルを開きます。自動的にマニフェスト デザイナーでマニフェストが開かれます。

  2. [アプリケーション] タブを開き、"最小幅" フィールドを探します。

  3. ドロップダウン リストを使って、最小幅を 320 px に変更します。

  4. テキスト エディターで package.appxmanifest マニフェスト ファイルを開くと、VisualElements 要素の子として ApplicationView 要素が表示されます。たとえば、マニフェスト ファイル内の新しい最小幅は次のようになります。

    <ApplicationView MinWidth="width320" /> 
    

これでアプリは 320 ピクセルまでサイズ変更できるようになったため、狭い幅でも問題なく使うことができるようにアプリを修正する必要があります。具体的には、水平方向ではなく垂直方向にパンするようにアプリを変更します。

グループと項目のビューに対する動作の定義

  1. pages\groupedItems\groupedItems.js ファイルで、ui.Pages.define 関数の ready メソッドにコードを追加します。このメソッドは、すべてのページの初期化とレンダリングが完了した後に呼び出されます。このメソッドでは、この後で定義する _initializeLayout 関数を呼び出します。(追加する必要のあるコードは *** START ****** END *** のコメントで示してあります。)

    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        ready: function (element, options) {
            var listView = element.querySelector(".groupeditemslist").winControl;
            listView.element.focus();
            // *** START ***
            this._initializeLayout(listView);
            // *** END ***
        },
        // ...
    
  2. groupedItems.js ファイルで、ui.Pages.define 関数の updateLayout メソッドにコードを追加します。このメソッドは、ユーザーがアプリのレイアウト状態 (狭い幅、縦方向、横方向) を切り替えるたびに呼び出されます。このメソッドで、ページの ListView コントロールを参照し、ページのアニメーションを一時的に使用できないようにしたうえで、この後定義する _initializeLayout 関数を呼び出します。

    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        updateLayout: function (element) {
            /// <param name="element" domElement="true" />
    
            // TODO: Respond to changes in layout.
            // *** START ***
            var listView = element.querySelector(".groupeditemslist").winControl;
    
            // Don't show page entrance animations when the app switches layouts.
            var handler = function (e) {
                listView.removeEventListener("contentanimating", handler, false);
                e.preventDefault;
            }
            listView.addEventListener("contentanimating", handler, false);
    
            this._initializeLayout(listView);
            // *** END ***
        },
        // ...
    
  3. groupedItems.js ファイルの ui.Pages.define 関数に、_initializeLayout 関数を定義するコードを追加します。この関数は、ページのレイアウト状態 (幅狭、縦方向、横方向) を調べ、ページの ListView コントロールを適宜調整します。readyupdateLayout の両方のメソッドで、この関数が呼び出されます。この関数で行われる処理は次のとおりです。

    • ページの幅が 320 ピクセルより大きく、500 ピクセル未満である場合、ページの ListView コントロールには、縦方向にスクロールするリストとして、グループのみのデータが表示されます。(幅 500 ピクセルというのはあくまで例です。どれくらいの幅になったときにレイアウトの変更を行うかは自由に決めることができます。このサンプルでは、アプリのレイアウトを切り替えるポイントとして 500 ピクセルを選びました。500 ピクセル未満のすべての幅で、アプリは狭い幅のレイアウトを使います。)
    • ページの幅が高さ未満の場合、ListView コントロールには、縦方向にスクロールするリストとして、項目を含んだグループのデータが表示されます。
    • それ以外の場合、ListView コントロールには、横方向にスクロールするグリッドとして、項目を含んだグループのデータが表示されます。
    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        // *** START ***
        _initializeLayout: function (listView) {
            // Narrow layout.
            if (document.documentElement.offsetWidth < 500) {
                // Show data as a vertically-scrolling list of groups only.
                listView.itemDataSource = Data.groups.dataSource;
                listView.groupDataSource = null;
                listView.layout = new ui.ListLayout();                
            }
            // Portait layout.
            else if (document.documentElement.offsetWidth < document.documentElement.offsetHeight) {
                // Show data as as a vertically-scrolling list of groups that contain items.
                listView.itemDataSource = Data.items.dataSource;
                listView.groupDataSource = Data.groups.dataSource;
                listView.layout = new ui.ListLayout();                                
            }
            // Landscape layout.
            else {
                // Show data as a horizontally-scrolling grid of groups contain items.
                listView.itemDataSource = Data.items.dataSource;
                listView.groupDataSource = Data.groups.dataSource;
                listView.layout = new ui.GridLayout();
            }
        },
        // *** END ***
        // ...
    

グループの詳細と項目の詳細のビューに対する動作の定義

  1. pages\groupDetail\groupDetail.js ファイルで、ui.Pages.define 関数の updateLayout メソッドにコードを追加します。このメソッドは、ユーザーがアプリのレイアウト状態 (縦方向と横方向) を切り替えるたびに呼び出されます。このメソッドで、ページの ListView コントロールを参照し、ページのアニメーションを一時的に使用できないようにしたうえで、この後定義する _initializeLayout 関数を呼び出します。加えて、正しい項目が最初に表示されるように ListView コントロールをスクロールします。

    ui.Pages.define("/pages/groupDetail/groupDetail.html", {
        // ...
        updateLayout: function (element) {
            /// <param name="element" domElement="true" />
    
            // TODO: Respond to changes in layout.
            // *** START ***
            var listView = element.querySelector(".itemslist").winControl;
    
            // Don't show page entrance animations when the app switches layouts.
            var handler = function (e) {
                listView.removeEventListener("contentanimating", handler, false);
                e.preventDefault();
            }
            listView.addEventListener("contentanimating", handler, false);
    
            var firstVisible = listView.indexOfFirstVisible;
    
            this._initializeLayout(listView);
    
            if (firstVisible >= 0 && listView.itemDataSource.list.length > 0) {
                listView.indexOfFirstVisible = firstVisible;
            }
            // *** END ***
        },
        // ...
    
  2. groupDetail.js ファイルの ui.Pages.define 関数に、_initializeLayout 関数を定義するコードを追加します。この関数は、ページのレイアウト状態 (縦方向または横方向) を調べ、ページのコントロールを適宜調整します。updateLayout メソッドがこの関数を呼び出します。この関数で行われる処理は次のとおりです。

    • ページの幅が 320 ピクセルより大きく、500 ピクセル未満である場合、ページの ListView コントロールには、縦方向にスクロールするリストとして、グループのみのデータが表示されます。(幅 500 ピクセルというのはあくまで例です。どれくらいの幅になったときにレイアウトの変更を行うかは自由に決めることができます。このサンプルでは、アプリのレイアウトを切り替えるポイントとして 500 ピクセルを選びました。500 ピクセル未満のすべての幅で、アプリは狭い幅のレイアウトを使います。)
    • ページの幅が高さ未満の場合、ListView コントロールには、縦方向にスクロールするリストとしてデータが表示されます。グループ ヘッダーは表示されません。
    • それ以外の場合、ListView コントロールには、横方向にスクロールするグリッドとしてデータが表示されます。グループ ヘッダーが左側に表示されます。
    ui.Pages.define("/pages/groupDetail/groupDetail.html", {
        // ...
        // *** START ***
        _initializeLayout: function (listView) {
            // Portrait layout.
            if (document.documentElement.offsetWidth < document.documentElement.offsetHeight) {
                listView.layout = new ui.ListLayout();
                var header = document.getElementsByTagName("header");
                header.item(0).style.display = "none";
            }
            // Landscape layout.
            else {
                listView.layout = new ui.GridLayout({ groupHeaderPosition: "left" });
                var header = document.getElementsByTagName("header");
                header.item(0).style.display = "inherit";
            }
        },
        // *** END ***
        // ...
    

レイアウトの切り替え

ここで、ウィンドウのサイズを切り替えたときにアプリのレイアウトがどうなるかを見てみましょう。

  1. Visual Studio からシミュレーターでアプリを起動します。(詳しくは、「シミュレーターでの Windows ストア アプリの実行」をご覧ください。)
  2. [基本タッチ モード] をクリックします。
  3. ページの一番上を横にドラッグし、ページの幅が 500 ピクセルとなるように区切り線を移動します。 項目を含んだグループのデータが、縦方向にスクロールするリストとして表示されます。
  4. ページの幅が 320 ピクセルとなるように区切り線を移動します。グループのみのデータが、縦方向にスクロールするリストとして表示されます。
  5. [右回りに回転] をタップまたはクリックします。項目を含んだグループのデータが、縦方向にスクロールするリストとして表示されます。
  6. グループのタイトル、項目のタイトル、戻るボタンなどをタップしたり、ページの幅やデバイスの向きを変えてみてください。

要約

狭い幅のレイアウトや縦長のレイアウトで適切に表示され、正しく機能するアプリを設計する方法について説明しました。

関連トピック

クイック スタート: アプリ レイアウトの定義