Hierarchická navigace

Třída NavigationPage poskytuje hierarchické navigační prostředí, kde uživatel může procházet stránky, dopředu a zpět podle potřeby. Třída implementuje navigaci jako poslední, první out (LIFO) zásobník objektů Page. Tento článek ukazuje, jak použít NavigationPage třídy k provádění navigace v zásobníku stránek.

Pokud chcete přejít z jedné stránky na jinou, aplikace nasdílí novou stránku do navigačního zásobníku, kde se stane aktivní stránkou, jak je znázorněno v následujícím diagramu:

Nasdílením stránky do zásobníku navigace

Pokud se chcete vrátit zpět na předchozí stránku, aplikace otevře aktuální stránku z navigačního zásobníku a nová horní stránka se stane aktivní stránkou, jak je znázorněno v následujícím diagramu:

Popping a Page from the Navigation Stack

Navigační metody jsou zpřístupněny Navigation vlastností u všech Page odvozených typů. Tyto metody poskytují možnost nasdílení stránek do navigačního zásobníku, k překryvům stránek z navigačního zásobníku a k provádění manipulace se zásobníky.

Provádění navigace

V hierarchické navigaci NavigationPage se třída používá k procházení zásobníku ContentPage objektů. Následující snímky obrazovky ukazují hlavní komponenty NavigationPage jednotlivých platforem:

Komponenty aplikace NavigationPage

Rozložení platformy NavigationPage závisí na této platformě:

  • V iOSu se v horní části stránky nachází navigační panel, který zobrazuje název a který obsahuje tlačítko Zpět , které se vrátí na předchozí stránku.
  • V Androidu se v horní části stránky nachází navigační panel, který zobrazuje název, ikonu a tlačítko Zpět , které se vrátí na předchozí stránku. Ikona je definována v atributu [Activity] , který ozdobí MainActivity třídu v projektu specifickém pro platformu Android.
  • Na Univerzální platforma Windows je v horní části stránky zobrazen navigační panel, který zobrazuje název.

Na všech platformách se hodnota Page.Title vlastnosti zobrazí jako název stránky. Kromě toho IconColor lze vlastnost nastavit na Color ikonu v navigačním panelu.

Poznámka:

Doporučuje NavigationPage se naplnit pouze instancemi ContentPage .

Vytvoření kořenové stránky

První stránka přidaná do navigačního zásobníku se označuje jako kořenová stránka aplikace a následující příklad kódu ukazuje, jak toho lze dosáhnout:

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

To způsobí Page1Xaml ContentPage , že instance bude vložena do navigačního zásobníku, kde se stane aktivní stránkou a kořenovou stránkou aplikace. Toto je znázorněno na následujících snímcích obrazovky:

Kořenová stránka navigačního zásobníku

Poznámka:

Vlastnost RootPage NavigationPage instance poskytuje přístup k první stránce v navigačním zásobníku.

Nasdílením stránek do navigačního zásobníku

Chcete-li přejít na Page2Xaml, je nutné vyvolat metodu PushAsync na Navigation vlastnosti aktuální stránky, jak je znázorněno v následujícím příkladu kódu:

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

To způsobí Page2Xaml , že instance bude vložena do navigačního zásobníku, kde se stane aktivní stránkou. Toto je znázorněno na následujících snímcích obrazovky:

Stránka vložená do navigačního zásobníku

PushAsync Při vyvolání metody dojde k následujícím událostem:

  • Volání PushAsync stránky má vyvoláno jeho OnDisappearing přepsání.
  • Stránka, na kterou se prochází, má vyvoláno její OnAppearing přepsání.
  • Úkol PushAsync se dokončí.

Přesné pořadí, ve kterém k těmto událostem dochází, je však závislé na platformě. Další informace naleznete v kapitole 24 Charles Petzold knihy Xamarin.Forms .

Poznámka:

OnDisappearing Volání a OnAppearing přepsání nelze považovat za zaručené označení navigace na stránce. Například v iOSu OnDisappearing se přepsání volá na aktivní stránce při ukončení aplikace.

Překryvné stránky ze zásobníku navigace

Aktivní stránku můžete z navigačního zásobníku přeskočit stisknutím tlačítka Zpět na zařízení bez ohledu na to, jestli se jedná o fyzické tlačítko na zařízení nebo tlačítko na obrazovce.

Aby se instance programově vrátila na původní stránku, Page2Xaml musí vyvolat metodu PopAsync , jak je znázorněno v následujícím příkladu kódu:

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

To způsobí Page2Xaml , že instance bude odebrána z navigačního zásobníku, přičemž nová horní stránka se stane aktivní stránkou. PopAsync Při vyvolání metody dojde k následujícím událostem:

  • Volání PopAsync stránky má vyvoláno jeho OnDisappearing přepsání.
  • Vrácená stránka má vyvoláno jeho OnAppearing přepsání.
  • Úkol PopAsync se vrátí.

Přesné pořadí, ve kterém k těmto událostem dochází, je však závislé na platformě. Další informace naleznete v kapitole 24 Charles Petzold knihy Xamarin.Forms .

PushAsync PopAsync Vlastnost každé stránky poskytuje také metodu Navigation PopToRootAsync, která je znázorněna v následujícím příkladu kódu:

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

Tato metoda zobrazí všechny kromě kořenového adresáře Page v navigačním zásobníku, takže kořenová stránka aplikace bude aktivní.

Animace přechodů stránek

Vlastnost Navigation každé stránky také poskytuje přepisované metody push a pop, které obsahují boolean parametr, který určuje, zda se má během navigace zobrazit animace stránky, jak je znázorněno v následujícím příkladu kódu:

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);
}

Nastavením parametru boolean zakážete false animaci přechodu stránky a zároveň nastavíte parametr tak, aby true umožňoval animaci přechodu na stránku za předpokladu, že je podporována podkladovou platformou. Metody push a pop, které tento parametr nemají, však ve výchozím nastavení umožňují animaci.

Předávání dat při navigaci

Někdy je potřeba, aby stránka během navigace předávala data do jiné stránky. Dvě techniky, jak toho dosáhnout, jsou předávání dat prostřednictvím konstruktoru stránky a nastavením nové stránky BindingContext na data. Každý z nich se teď bude probírat.

Předávání dat pomocí konstruktoru stránky

Nejjednodušší technika předávání dat na jinou stránku během navigace je prostřednictvím parametru konstruktoru stránky, který je znázorněn v následujícím příkladu kódu:

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

Tento kód vytvoří MainPage instanci, která předává aktuální datum a čas ve formátu ISO8601, který je zabalen do NavigationPage instance.

Instance MainPage přijímá data prostřednictvím parametru konstruktoru, jak je znázorněno v následujícím příkladu kódu:

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

Data se pak zobrazí na stránce nastavením Label.Text vlastnosti, jak je znázorněno na následujících snímcích obrazovky:

Data předávaná prostřednictvím konstruktoru stránky

Předávání dat přes BindingContext

Alternativním přístupem pro předávání dat na jinou stránku během navigace je nastavení nové stránky BindingContext na data, jak je znázorněno v následujícím příkladu kódu:

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);
}

Tento kód nastaví BindingContext SecondPage instanci na Contact instanci a pak přejde na SecondPage.

Potom SecondPage pomocí datové vazby zobrazí Contact data instance, jak je znázorněno v následujícím příkladu kódu XAML:

<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>

Následující příklad kódu ukazuje, jak lze datovou vazbu provést v jazyce 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 ();
  }
}

Data se pak zobrazí na stránce pomocí řady ovládacích Label prvků, jak je znázorněno na následujících snímcích obrazovky:

Data předávaná prostřednictvím BindingContext

Další informace o datové vazbě najdete v tématu Základy datových vazeb.

Manipulace se zásobníkem navigace

Vlastnost Navigation zveřejňuje NavigationStack vlastnost, ze které lze získat stránky v navigačním zásobníku. Zatímco Xamarin.Forms udržuje přístup k navigačnímu zásobníku, Navigation vlastnost poskytuje InsertPageBefore a RemovePage metody pro manipulaci se zásobníkem vložením stránek nebo jejich odebráním.

Metoda InsertPageBefore vloží zadanou stránku do navigačního zásobníku před existující zadanou stránku, jak je znázorněno v následujícím diagramu:

Vložení stránky do navigačního zásobníku

Metoda RemovePage odebere zadanou stránku z navigačního zásobníku, jak je znázorněno v následujícím diagramu:

Odebrání stránky z navigačního zásobníku

Tyto metody umožňují vlastní navigační prostředí, například nahrazení přihlašovací stránky novou stránkou po úspěšném přihlášení. Následující příklad kódu ukazuje tento scénář:

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
  }
}

Za předpokladu, že jsou přihlašovací údaje uživatele správné, MainPage instance se vloží do navigačního zásobníku před aktuální stránku. Metoda PopAsync pak odebere aktuální stránku z navigačního zásobníku a MainPage instance se stane aktivní stránkou.

Zobrazení v navigačním panelu

Všechny Xamarin.FormsView lze zobrazit v navigačním panelu .NavigationPage To se provádí nastavením NavigationPage.TitleView připojené vlastnosti na hodnotu View. Tuto připojenou vlastnost lze nastavit na libovolném Pagea při Page nasdílení na NavigationPage, NavigationPage bude respektovat hodnotu vlastnosti.

Následující příklad ukazuje, jak nastavit připojenou NavigationPage.TitleView vlastnost z 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>

Tady je ekvivalentní kód jazyka C#:

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

Slider Výsledkem je zobrazení v navigačním panelu NavigationPagena :

Posuvník TitleView

Důležité

Mnoho zobrazení se na navigačním panelu nezobrazí, pokud není zadána velikost zobrazení s vlastnostmi a HeightRequest vlastnostmiWidthRequest. Případně můžete zobrazení zabalit do objektu StackLayout HorizontalOptions s vlastnostmi nastavenými VerticalOptions na odpovídající hodnoty.

Všimněte si, že vzhledem k tomu Layout , že třída je odvozena od View třídy, může být připojená vlastnost nastavena tak, TitleView aby zobrazovala třídu rozložení, která obsahuje více zobrazení. V iOSu a Univerzální platforma Windows (UPW) nejde změnit výšku navigačního panelu, takže výřez se zobrazí, pokud je zobrazení zobrazené v navigačním panelu větší než výchozí velikost navigačního panelu. Na Androidu je však možné výšku navigačního panelu změnit nastavením NavigationPage.BarHeight vlastnosti bindable na double představující novou výšku. Další informace naleznete v tématu Nastavení výšky navigačního panelu na navigationPage.

Případně můžete rozšířený navigační panel navrhovat umístěním některého obsahu do navigačního panelu a některé v zobrazení v horní části obsahu stránky, který se shoduje s navigačním panelem. Kromě toho lze v iOSu odebrat oddělovací čáru a stín, který je v dolní části navigačního panelu, nastavením NavigationPage.HideNavigationBarSeparator vlastnosti bindable na true. Další informace naleznete v tématu Skrytí oddělovače navigačního panelu na navigationPage.

Poznámka:

Vlastnosti BackButtonTitlea , TitleIconTitleTitleView mohou definovat hodnoty, které zabírají místo na navigačním panelu. I když se velikost navigačního panelu liší podle platformy a velikosti obrazovky, nastavení všech těchto vlastností způsobí konflikty kvůli omezenému dostupnému prostoru. Místo toho, abyste se pokusili použít kombinaci těchto vlastností, můžete zjistit, že můžete lépe dosáhnout požadovaného návrhu navigačního panelu TitleView pouze nastavením vlastnosti.

Omezení

Při zobrazení View na navigačním panelu NavigationPage:

  • V iOSu se zobrazení umístěná na navigačním panelu NavigationPage zobrazují na jiné pozici v závislosti na tom, jestli jsou povolené velké názvy. Další informace o povolení velkých názvů najdete v tématu Zobrazení velkých názvů.
  • V Androidu lze umístění zobrazení do navigačního panelu provést NavigationPage pouze v aplikacích, které používají kompatibilitu aplikací.
  • Nedoporučuje se umístit velká a složitá zobrazení, například ListView a TableView, na navigačním panelu .NavigationPage