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:
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:
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:
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:
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:
PushAsync
Při vyvolání metody dojde k následujícím událostem:
- Volání
PushAsync
stránky má vyvoláno jehoOnDisappearing
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 jehoOnDisappearing
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:
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:
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:
Metoda RemovePage
odebere zadanou stránku z navigačního zásobníku, jak je znázorněno v následujícím diagramu:
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 Page
a 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 NavigationPage
na :
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 BackButtonTitle
a , TitleIcon
Title
TitleView
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
aTableView
, na navigačním panelu .NavigationPage