次の方法で共有


第 24 章の概要: ページの移動

Note

この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。

多くのアプリケーションは、ユーザーが移動する複数のページで構成されています。 アプリケーションには、必ず main ページまたは home ページがあり、元の場所に戻るためにスタックに保持されている他のページに、ユーザーはそのページから移動します。 その他のナビゲーション オプションについては、「第 25 章:ページの変数」を参照してください。

VisualElement には、INavigation 型の Navigation プロパティが定義されています。これには、新しいページに移動するための以下の 2 つのメソッドが含まれます。

いずれのメソッドも、引数として Page インスタンスを取り、Task オブジェクトを返します。 以下の 2 つのメソッドでは、前のページに戻ります。

(Android と Windows Phone の場合のように) ユーザー インターフェイスに独自の [戻る] ボタンがある場合、アプリケーションがこれらのメソッドを呼び出す必要はありません。

これらのメソッドはすべての VisualElement から使用できますが、通常は、現在の Page インスタンスの Navigation プロパティから呼び出します。

ユーザーが前のページに戻る前にページに情報を指定する必要がある場合、アプリケーションでは通常モーダル ページを使用します。 モーダルではないページは、モードレスまたは "階層" と呼ばれます。 ページ自体には、それがモーダルであるか、モードレスであるかを区別するものは含まれません。代わりに、それへの移動に使用されるメソッドによって管理されています。 モーダル ページがすべてのプラットフォームで動作するには、前のページに戻る独自のユーザー インターフェイスを備えている必要があります。

ModelessAndModal サンプルでは、モードレス ページとモーダル ページの違いを確認できます。 ページ ナビゲーションを使用するすべてのアプリケーションでは、プログラムの App クラスに一般的に含まれる NavigationPage コンストラクターにそのホーム ページを渡す必要があります。 これの利点の 1 つとして、iOS のページでは Padding を設定する必要がありません。

これはモードレス ページで、ページの Title プロパティが表示されることからわかります。 iOS、Android、Windows タブレットおよびデスクトップのすべてのプラットフォームに、前のページに戻るユーザー インターフェイス要素が用意されています。 Android デバイスと Windows Phone デバイスにももちろん、元に戻るための [戻る] ボタンがあります。

モーダル ページでは、ページ Title が表示されず、前のページに戻るユーザー インターフェイス要素がありません。 Android と Windows Phone では標準の [戻る] ボタンを使用して前のページに戻れますが、他のプラットフォームではモーダル ページに、元に戻るための独自のメカニズムを用意する必要があります。

アニメーションでのページ切り替え

ページの切り替えにアニメーションを含めたい場合に、さまざまなナビゲーション メソッドの別のバージョンを使用するために使用する 2 番目のブール値引数を true に設定する必要があります。

ただし、標準のページナビゲーション メソッドにはアニメーションが既定で含まれているため、起動時に特定のページに移動する場合 (この章の終わり近くを参照) または独自の開始アニメーションを提供する場合 (「第 22 章:アニメーション」を参照) のみ、これらは必要です。

ビジュアルと機能のバリエーション

NavigationPage には、お使いの App メソッドでクラスをインスタンス化するときに設定できる以下の 2 つのプロパティがあります。

NavigationPage には、それらが設定されている特定のページに影響する、以下の 4 つの接続されている連結可能なプロパティもあります。

機構を調べる

ページ ナビゲーション メソッドはすべて非同期であり、await と共に使用される必要があります。 完了はページ ナビゲーションの完了ではなく、ページ ナビゲーション スタックを確認するのが安全であるということのみを意味します。

あるページから別のページに移動する場合、通常、最初のページではその OnDisappearing メソッドに対する呼び出しが取得され、2 番目のページでは OnAppearing メソッドに対する呼び出しが取得されます。 同様に、あるページから別のページに戻る場合、最初のページではその OnDisappearing メソッドに対する呼び出しが取得され、2 番目のページでは通常、OnAppearing メソッドに対する呼び出しが取得されます。 これらの呼び出しの順番 (およびナビゲーションを呼び出す非同期メソッドの完了) は、プラットフォームによって異なります。 前の 2 つの文で "通常" という語を使用しているのは、Android モーダルページ ナビゲーションではこれらのメソッド呼び出しが発生しないためです。

また、OnAppearing および OnDisappearing のメソッド呼び出しは、必ずしもページ ナビゲーションを意味しません。

INavigation インターフェイスには、ナビゲーション スタックを確認できる、以下の 2 つのコレクション プロパティがあります。

  • モードレス スタック用の IReadOnlyList<Page> 型の NavigationStack
  • モダール スタック用の IReadOnlyList<Page> 型の ModalStack

これらのスタックには、NavigationPage (App クラスの MainPage プロパティ) の Navigation プロパティからアクセスするのが最も安全です。 これらのスタックの確認は、非同期のページ ナビゲーション メソッドが完了した後のみ安全です。 現在のページがモーダル ページである場合、NavigationPageCurrentPage プロパティはそれが現在のページではなく、最後のモードレス ページであることを示します。

SinglePageNavigation サンプルでは、ページ ナビゲーションとそのスタック、およびページ ナビゲーションの正当な種類を調べることができます。

  • モードレス ページでは、別のモードレス ページまたはモーダル ページに移動できる
  • モーダル ページでは、別のモーダル ページにのみ移動できる

モダリティの適用

アプリケーションでは、ユーザーからいくつかの情報を取得する必要がある場合に、モーダル ページが使用されます。 ユーザーは、その情報が提供されるまで、前のページに戻ることはできません。 iOS では、ユーザーがそのページを終了した場合にのみ [戻る] ボタンを用意して有効にすることが簡単にできます。 しかし、Android デバイスと Windows Phone デバイスでは、プログラムで [戻る] ボタン自体が処理された場合、アプリケーションが OnBackButtonPressed メソッドをオーバーライドし、true を返す必要があります (ModalEnforcement のサンプルを参照)。

MvvmEnforcement サンプルでは、この動作を MVVM シナリオで示しています。

特定のモーダル ページに複数回移動できる場合、ユーザーがそこにすべての情報を再入力するのではなく、そこで情報を編集できるように、情報が保持されている必要があります。 これは、モーダル ページの特定のインスタンスを保持することで対応できますが、(特に iOS では) ビュー モデルで情報を保持した方がより便利です。

ナビゲーション メニューの作成

ViewGalleryType サンプルでは、TableView を使用してメニュー項目が一覧表示されています。 各項目には、特定のページの Type オブジェクトが関連付けられています。 その項目が選択されると、プログラムがそのページをインスタンス化し、それに移動できます。

View Gallery Type のトリプル スクリーンショット

ViewGalleryInst サンプルは、型ではなくメニューに各ページのインスタンスが含まれている点で、少し異なります。 これは各ページの情報を保持するのに役立ちますが、すべてのページがプログラムの起動時にインスタンス化される必要があります。

ナビゲーション スタックの操作

StackManipulation では、INavigation で定義されたナビゲーション スタックを構造化して操作するためのいくつかの関数が示されています。

ページの動的生成

BuildAPage サンプルでは、ユーザー入力に基づいて実行時にページを構築する方法を示しています。

データ転送のパターン

移動先のページにデータを移動したり、そのページを呼び出したページにデータを戻したりするために、ページ間ではしばしばデータが共有される必要があります。 これを行うには、いくつかの方法があります。

コンストラクターの引数

新しいページに移動する場合、ページ自体の初期化を許可するコンストラクター引数を使用してページ クラスをインスタンス化できます。 この方法は、SchoolAndStudents サンプルで示されています。 移動先のページの BindingContext をそれの移動元のページで設定することもできます。

プロパティとメソッド呼び出し

残りのデータ転送の例では、あるページから別のページに移動して戻るとき、ページ間で情報を渡す問題について説明します。 これらの説明では、home ページから info ページに移動し、info ページに初期化された情報が転送される必要があります。 info ページでは、ユーザーから追加情報を取得し、その情報を home ページに転送します。

home ページでは、そのページがインスタンス化されるとすぐに info ページのパブリック メソッドとプロパティに簡単にアクセスできるようになります。 info ページでも、home ページのパブリック メソッドとプロパティにアクセスできますが、それの適切なタイミングの選択が困難です。 DateTransfer1 サンプルでは、OnDisappearing のオーバーライドでこれを行います。 1 つの欠点として、info ページで home ページの型が認識されている必要があります。

MessagingCenter

Xamarin.FormsMessagingCenter クラスには、2 つのページ間で相互に通信するための別の方法が用意されています。 メッセージはテキスト文字列で識別され、任意のオブジェクトと共に使用されます。

特定の型からメッセージを受け取るプログラムでは、MessagingCenter.Subscribe を使用してそれにサブスクライブし、コールバック関数を指定する必要があります。 サブスクライブを解除するには、後で MessagingCenter.Unsubscribe を呼び出します。 コールバック関数は、Send メソッドを介して送信された指定済みの名前を使用する、指定された型から送信されたすべてのメッセージを受信します。

DateTransfer2 プログラムでは、メッセージング センターを使用してデータを転送する方法を示していますが、この場合も、info ページが home ページの型を認識している必要があります。

イベント

イベントとは、あるクラスが型がわからない別のクラスに情報を送信するための、従来からの手法です。 DateTransfer3 のサンプルの info クラスでは、情報の準備が整ったときに呼び出されるイベントが定義されています。 ただし、home ページがイベント ハンドラーをデタッチするのに適切な場所がありません。

App クラスでの中継

DateTransfer4 サンプルでは、home ページと info ページの両方で App クラスに定義されているプロパティにアクセスする方法を示しています。 これは適切な解決策ですが、以下のセクションではさらに適切なものを説明しています。

ViewModel への切り替え

情報に ViewModel を使用すると、home ページと info ページで情報クラスのインスタンスを共有できます。 これは、DateTransfer5 サンプルに示されています。

ページの状態の保存と復元

App クラスでの中継または ViewModel の手法は、info ページがアクティブな間にプログラムがスリープ状態になるアプリケーションで、情報を保存する必要がある場合に最適です。 これは、DateTransfer6 サンプルで示されています。

ナビゲーション スタックの保存と復元

スリープ状態になる複数ページのプログラムでは、一般的に復元時に同じページに移動する必要があります。 つまり、このようなプログラムでは、ナビゲーション スタックの内容が保存される必要があります。 このセクションでは、この目的のために設計されたクラスで、このプロセスを自動化する方法について説明します。 また、このクラスでは個々のページを呼び出して、それらのページの状態を保存および復元できるようにします。

Xamarin.FormsBook.Toolkit ライブラリには、Properties ディクショナリに項目を保存および復元するためにクラスで実装できる IPersistantPage という名前のインターフェイスが定義されています。

Xamarin.FormsBook.Toolkit ライブラリの MultiPageRestorableApp クラスは Application から派生しています。 その後、MultiPageRestorableApp から使用する App クラスを派生させ、いくつかのハウスキープ処理を実行できます。

StackRestoreDemo では、MultiPageRestorableApp の使用方法を示しています。

実在しているようなアプリ

NoteTaker サンプルでも MultiPageRestorableApp を使用して、Properties ディクショナリに保存されているメモを入力および編集できます。