階層ナビゲーション

サンプルのダウンロード サンプルをダウンロードする

NavigationPage クラスは、ユーザーが前後を希望どおりにページを移動することができる階層ナビゲーション エクスペリエンスを提供します。 このクラスは、Page オブジェクトの後入れ先出し (LIFO) スタックとしてナビゲーションを提供します。 この記事では、NavigationPage クラスを使用してページのスタックでナビゲーションを実行する方法について説明します。

1 つのページから別のページに移動するには、次の図に示すように、アプリケーションは新しいページを、そこでアクティブなページとなるナビゲーション スタックにプッシュします。

ナビゲーションスタックへのページのプッシュ

次の図に示すように、前のページに戻るには、アプリケーションは現在のページをナビゲーション スタックからポップします。そして新しい最上位のページがアクティブ ページになります。

ナビゲーションスタックからページをポップする

ナビゲーションメソッドは、 Navigation 任意の派生型の Xamarin_Forms _NavigableElement_Navigation "linktype =" absolute path ">プロパティによって公開され Page ます。 これらのメソッドには、ページをナビゲーション スタックにプッシュし、ナビゲーション スタックからページをポップし、スタック操作を実行する機能があります。

ナビゲーションを実行する

階層ナビゲーションでは、NavigationPage クラスは ContentPage オブジェクトのスタック間をナビゲートするために使用されます。 次のスクリーンショットは、各プラットフォームでの NavigationPage のメイン コンポーネントを示します。

NavigationPage コンポーネント

NavigationPage のレイアウトは、プラットフォームによって異なります。

  • iOS では、ナビゲーション バーがページの上部にあり、タイトルが表示され、前のページに戻る [戻る] ボタンがあります。
  • Android では、ナビゲーション バーがページの上部にあり、タイトル、アイコンと、前のページに戻る [戻る] ボタンが表示されています。 Android プラットフォーム固有プロジェクトでは、アイコンは MainActivity クラスを修飾する [Activity] 属性で定義されています。
  • ユニバーサル Windows プラットフォームでは、ナビゲーション バーはページの上部にあり、タイトルが表示されています。

すべてのプラットフォームで、Xamarin_Forms の値 _Page_Title "linktype =" absolute path ">Page.Title プロパティがページタイトルとして表示されます。 さらに、IconColor プロパティを、ナビゲーション バーのアイコンに適用される Color に設定できます。

Note

NavigationPageContentPage インスタンスのみで作成することをお勧めします。

ルート ページを作成する

ナビゲーション スタックに追加された最初のページは、アプリケーションのルート ページとなります。次のコード例に、これを実現する方法を示しています。

public App ()
{
  MainPage = new NavigationPage (new Page1Xaml ());
}

これにより、Page1XamlContentPage インスタンスがナビゲーション スタックにプッシュされるようになります。そこがアクティブ ページであり、アプリケーションのルート ページとなります。 これを次のスクリーンショットに示します。

ナビゲーションスタックのルートページ

Note

Xamarin_Forms _NavigationPage_RootPage、インスタンスの "linktype =" 絶対パス ">プロパティによって、 RootPageNavigationPage ナビゲーションスタックの最初のページにアクセスできます。

ナビゲーション スタックにページをプッシュする

に移動するに Page2Xaml は、 PushAsync 次の Page2XamlNavigation コード例に示すように、現在のページの Xamarin_Forms _NavigableElement_Navigation "linktype =" absolute path ">プロパティに対してメソッドを呼び出す必要があります。

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PushAsync (new Page2Xaml ());
}

これにより、Page2Xaml インスタンスがナビゲーション スタックにプッシュされるようになり、そこがアクティブ ページとなります。 これを次のスクリーンショットに示します。

ナビゲーションスタックにプッシュされたページ

PushAsync メソッドが呼び出されると、次のイベントが発生します。

  • 呼び出し元のページの PushAsync Xamarin_Forms PushAsync _Page_OnDisappearing "linktype =" absolute path ">OnDisappearing override が呼び出されます。
  • 移動先のページの Xamarin_Forms _Page_OnAppearing "linktype =" absolute path ">OnAppearing オーバーライドが呼び出されます。
  • PushAsync タスクが完了します。

ただし、これらのイベントが発生する正確な順序はプラットフォームによって異なります。 詳細については、チャールズ Petzold 著) の書籍の 第24章 を参照してください

Note

Xamarin_Forms の呼び出し _Page_OnDisappearing "linktype =" absolute path ">OnDisappearing および Xamarin_Forms OnDisappearing _Page_OnAppearing" linktype = "absolute path" >オーバーライドは、 OnAppearing ページナビゲーションの保証されたものとして扱うことはできません。 たとえば、iOS では、アプリケーションの終了時にアクティブ ページで OnDisappearing のオーバーライドが呼び出されます。

ナビゲーション スタックからページをポップする

アクティブ ページは、これが物理的なボタンであるか画面上のボタンであるかどうかにかかわらず、デバイスの [戻る] ボタンを押すことによってナビゲーション スタックからポップすることができます。

プログラムを使用して元のページに戻るには、 Page2XamlPage2Xaml 次の PopAsync コード例に示すように、インスタンスは Xamarin_Forms _NavigationPage_PopAsync "linktype =" absolute path ">メソッドを呼び出す必要があります。

async void OnPreviousPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PopAsync ();
}

これにより、ナビゲーション スタックから Page2Xaml インスタンスが削除され、新しい最上位のページがアクティブ ページとなります。 Xamarin_Forms _NavigationPage_PopAsync "linktype =" absolute path ">PopAsync メソッドが呼び出されると、次のイベントが発生します。

  • 呼び出し元のページの PopAsync Xamarin_Forms PopAsync _Page_OnDisappearing "linktype =" absolute path ">OnDisappearing override が呼び出されます。
  • 返されるページの Xamarin_Forms _Page_OnAppearing "linktype =" absolute path ">OnAppearing override が呼び出されます。
  • PopAsync タスクが復帰します。

ただし、これらのイベントが発生する正確な順序はプラットフォームによって異なります。 詳細については、チャールズ Petzold 著) の書籍の 第24章 を参照してください

PushAsyncおよび Xamarin_Forms PushAsync _NavigationPage_PopAsync "linktype =" absolute path ">メソッドに加えて、 PopAsync 各ページの Xamarin_Forms _NavigableElement_Navigation" data-linktype = "absolute path" >メソッドには、 NavigationPopAsyncPopToRootAsync 次のコード例に示すように、Xamarin_Forms "linktype =" absolute path "_NavigationPage_PopToRootAsync メソッドも用意されています。

async void OnRootPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PopToRootAsync ();
}

このメソッドは、ルート Page 以外のすべてをナビゲーション スタックからポップします。そのため、アプリケーションのルート ページがアクティブ ページになります。

ページ遷移をアニメーション化する

次の コード例に示すように、各ページの Xamarin_Forms _NavigableElement_Navigation "linktype =" absolute path ">プロパティには、 Navigationboolean ナビゲーション中にページアニメーションを表示するかどうかを制御するパラメーターを含む、オーバーライドされたプッシュメソッドと pop メソッドも用意されています。

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PushAsync (new Page2Xaml (), false);
}

async void OnPreviousPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PopAsync (false);
}

async void OnRootPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PopToRootAsync (false);
}

boolean パラメーターを false に設定すると、ページ遷移アニメーションが無効になります。また、パラメーターを true に設定すると、基となるプラットフォームでサポートされている場合はページ遷移アニメーションが有効になります。 ただし、プッシュとポップのメソッドでこのパラメーターが指定されていない場合は、既定でアニメーションが有効になります。

ナビゲーション時にデータを渡す

場合によっては、ナビゲーション中に、あるページから別のページにデータを渡す必要があります。 これを実現する2つの方法として、ページコンストラクターを使用してデータを渡し、新しいページの Xamarin_Forms _BindableObject_BindingContext "linktype =" absolute path ">BindingContext をデータに設定します。 これから、それぞれについて順番に説明します。

ページ コンストラクターを介してデータを渡す

ナビゲーション中に別のページにデータを渡す最も簡単な手法は、次のコード例で示すように、ページ コンストラクター パラメーターを使用することです。

public App ()
{
  MainPage = new NavigationPage (new MainPage (DateTime.Now.ToString ("u")));
}

このコードでは、現在の日付と時刻を ISO8601 形式で渡す MainPage インスタンスを作成します。これは NavigationPage インスタンスでラップされています。

MainPage インスタンスは、次のコード例に示すように、コンストラクター パラメーターを使用してデータを受け取ります。

public MainPage (string date)
{
  InitializeComponent ();
  dateLabel.Text = date;
}

その後、 Label.Text 次のスクリーンショットに示すように、Xamarin_Forms _Label_Text "linktype =" absolute path ">プロパティを設定することによって、データがページに表示されます。

ページコンストラクターを通じて渡されるデータ

BindingContext を介してデータを渡す

ナビゲーション中に別のページにデータを渡すための別の方法として、 BindingContext 次のコード例に示すように、新しいページの Xamarin_Forms _BindableObject_BindingContext "linktype =" absolute path ">をデータに設定します。

async void OnNavigateButtonClicked (object sender, EventArgs e)
{
  var contact = new Contact {
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
  };

  var secondPage = new SecondPage ();
  secondPage.BindingContext = contact;
  await Navigation.PushAsync (secondPage);
}

このコードは、 インスタンスの Xamarin_Forms _BindableObject_BindingContext "linktype =" absolute path ">をインスタンスに設定し、 BindingContextSecondPageContact に移動し SecondPage ます。

次の XAML コード例に示すように、SecondPage ではデータ バインディングを使用して Contact インスタンス データを表示します。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PassingData.SecondPage"
             Title="Second Page">
    <ContentPage.Content>
        <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
            <StackLayout Orientation="Horizontal">
                <Label Text="Name:" HorizontalOptions="FillAndExpand" />
                <Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" />
            </StackLayout>
            ...
            <Button x:Name="navigateButton" Text="Previous Page" Clicked="OnNavigateButtonClicked" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

次のコード例は、C# でデータ バインディングを実行する方法を示しています。

public class SecondPageCS : ContentPage
{
  public SecondPageCS ()
  {
    var nameLabel = new Label {
      FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
      FontAttributes = FontAttributes.Bold
    };
    nameLabel.SetBinding (Label.TextProperty, "Name");
    ...
    var navigateButton = new Button { Text = "Previous Page" };
    navigateButton.Clicked += OnNavigateButtonClicked;

    Content = new StackLayout {
      HorizontalOptions = LayoutOptions.Center,
      VerticalOptions = LayoutOptions.Center,
      Children = {
        new StackLayout {
          Orientation = StackOrientation.Horizontal,
          Children = {
            new Label{ Text = "Name:", FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)), HorizontalOptions = LayoutOptions.FillAndExpand },
            nameLabel
          }
        },
        ...
        navigateButton
      }
    };
  }

  async void OnNavigateButtonClicked (object sender, EventArgs e)
  {
    await Navigation.PopAsync ();
  }
}

次のスクリーンショットに示すように、一連の Label コントロールによってデータがページに表示されます。

BindingContext を通じて渡されるデータ

データ バインディングの詳細については、「Data Binding Basics」 (データ バインディングの基礎) を参照してください。

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

Xamarin_Forms _NavigableElement_Navigation "linktype =" absolute path ">プロパティは、 NavigationNavigationNavigationStack ナビゲーションスタック内のページを取得するための Xamarin_Forms _INavigation_NavigationStack" linktype = "絶対パス" >プロパティを公開します。 Xamarin.Forms はナビゲーション スタックへのアクセスを維持していますが、Navigation プロパティには、ページを挿入または削除することでスタックを操作するための InsertPageBefore および RemovePage メソッドが用意されています。

次の図に示すように、InsertPageBefore メソッドによって、ナビゲーション スタック内の指定されたページが既存の指定されたページの前に挿入されます。

ナビゲーションスタックへのページの挿入

次の図に示すように、RemovePage メソッドによって、指定されたページがナビゲーション スタックから削除されます。

ナビゲーションスタックからのページの削除

これらのメソッドを使用すると、ログインに成功した後に、ログイン ページを新しいページに置き換えるなど、カスタムのナビゲーション エクスペリエンスを実現できます。 次のコード例はこのシナリオを示しています。

async void OnLoginButtonClicked (object sender, EventArgs e)
{
  ...
  var isValid = AreCredentialsCorrect (user);
  if (isValid) {
    App.IsUserLoggedIn = true;
    Navigation.InsertPageBefore (new MainPage (), this);
    await Navigation.PopAsync ();
  } else {
    // Login failed
  }
}

ユーザーの資格情報が正しい場合、MainPage インスタンスは、ナビゲーション スタック内の現在のページの前に挿入されます。 Xamarin_Forms _NavigationPage_PopAsync "linktype =" absolute path ">メソッドによって、 PopAsync インスタンスがアクティブページになった状態で、ナビゲーションスタックから現在のページが削除され MainPage ます。

ナビゲーション バーにビューを表示する

Xamarin.FormsView は、のナビゲーションバーに表示でき NavigationPage ます。 これを実現するには、NavigationPage.TitleView 添付プロパティを View に設定します。 この添付プロパティは任意の Page に設定できます。また、PageNavigationPage にプッシュされると、NavigationPage ではプロパティの値が反映されます。

Title ビューのサンプルから抜粋した次の例では、 XAML から添付プロパティを設定する方法を示しています。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NavigationPageTitleView.TitleViewPage">
    <NavigationPage.TitleView>
        <Slider HeightRequest="44" WidthRequest="300" />
    </NavigationPage.TitleView>
    ...
</ContentPage>

C# での同等のコードを次に示します。

public class TitleViewPage : ContentPage
{
    public TitleViewPage()
    {
        var titleView = new Slider { HeightRequest = 44, WidthRequest = 300 };
        NavigationPage.SetTitleView(this, titleView);
        ...
    }
}

この結果、NavigationPage でナビゲーション バーに Slider が表示されます:

slider TitleView

重要

ビューのサイズが Xamarin_Forms _VisualElement_WidthRequest" data-linktype="absolute-path">および WidthRequest Xamarin_Forms WidthRequest _VisualElement_HeightRequest" data-linktype="absolute-path">HeightRequest プロパティで指定されていない限り、多くのビューはナビゲーション バーに表示されません。 または StackLayout 、Xamarin_Forms StackLayout _View_HorizontalOptions" data-linktype="absolute-path">and HorizontalOptions Xamarin_Forms _View_VerticalOptions" data-linktype="absolute-path">VerticalOptions プロパティを適切な値に設定して、ビューを にラップすることもできます。

Layout クラスは View クラスから派生しているため、複数のビューを含むレイアウト クラスを表示するように TitleView 添付プロパティを設定することができます。 iOS およびユニバーサル Windows プラットフォーム (UWP) では、ナビゲーション バーの高さを変更できないため、ナビゲーション バーに表示されるビューがナビゲーション バーの既定サイズより大きい場合、クリップが発生します。 一方 Android では、NavigationPage.BarHeight バインディング可能プロパティを新しい高さを表す double に設定することで、ナビゲーション バーの高さを変更できます。 詳細については、「Setting the Navigation Bar Height on a NavigationPage」(NavigationPage でナビゲーション バーの高さを設定する) を参照してください。

また、ナビゲーション バーにコンテンツの一部を配置し、ナビゲーション バーと色を合わせたビューの一部をページ コンテンツの上部に配置して、拡張ナビゲーション バーを提案することもできます。 さらに、iOS では、NavigationPage.HideNavigationBarSeparator バインド可能プロパティを true に設定することで、ナビゲーション バーの下部にあるセパレーターと影を削除できます。 詳細については、「Hiding the Navigation Bar Separator on a NavigationPage」(NavigationPage でナビゲーション バーのセパレーターを非表示にする) を参照してください。

Note

、Xamarin_Forms BackButtonTitleBackButtonTitle _Page_Title" data-linktype="absolute-path">、、および プロパティはすべて、ナビゲーション バーの領域を占有する値 TitleTitleIconTitleView を定義できます。 ナビゲーション バーのサイズはプラットフォームや画面サイズによって変わりますが、これらのプロパティをすべて設定すると、領域が限られているために競合が発生します。 これらのプロパティの組み合わせを使用するのではなく、TitleView プロパティのみ設定して目的のナビゲーション バーのデザインを改善することをお勧めします。

制限事項

NavigationPage のナビゲーション バーに View を表示するときに注意が必要な制限事項がいくつかあります。

  • iOS では、NavigationPage のナビゲーション バーに配置されるビューは、大きなタイトルが有効かどうかによって表示される位置が変わります。 大きなタイトルを有効にする方法については、「Displaying Large Titles」(大きなタイトルの表示) を参照してください。
  • Android では、NavigationPage のナビゲーション バーにビューを配置することは、app-compat を使用するアプリでのみ実現できます。
  • ListViewTableView などの大きくて複雑なビューを NavigationPage のナビゲーション バーに配置することはお勧めしません。