Xamarin.Forms: TabbedPage
Das Xamarin.FormsTabbedPage
besteht aus einer Liste von Registerkarten und einem größeren Detailbereich, wobei jeder Registerkarte Inhalt in den Detailbereich lädt. Die folgenden Screenshots zeigen eine TabbedPage
unter iOS und Android:
Unter iOS wird die Liste der Registerkarten am unteren Rand des Bildschirms angezeigt, und der Detailbereich befindet sich darüber. Jede Registerkarte besteht aus einem Titel und einem Symbol, bei dem es sich um eine PNG-Datei mit einem Alphakanal handeln sollte. Im Hochformat werden die Symbole der Registerkartenleiste über den Registerkartentiteln angezeigt. Im Querformat werden die Symbole und Titel nebeneinander angezeigt. Außerdem kann je nach Gerät und Ausrichtung eine reguläre oder kompakte Registerkartenleiste angezeigt werden. Wenn mehr als fünf Registerkarten vorhanden sind, wird die Registerkarte More (Weitere) angezeigt, die verwendet werden kann, um auf die zusätzlichen Registerkarten zuzugreifen.
Unter Android wird die Liste der Registerkarten am oberen Rand des Bildschirms angezeigt, und der Detailbereich befindet sich darunter. Jede Registerkarte besteht aus einem Titel und einem Symbol, bei dem es sich um eine PNG-Datei mit einem Alphakanal handeln sollte. Die Registerkarten können jedoch mit einem plattformspezifischen Element an den unteren Rand des Bildschirms verschoben werden. Wenn mehr als fünf Registerkarten vorhanden sind und die Registerkartenliste sich am unteren Rand des Bildschirms befindet, wird eine Registerkarte More (Weitere) angezeigt, die für den Zugriff auf zusätzliche Registerkarten verwendet werden kann. Weitere Informationen zu den Symbolanforderungen finden Sie unter Tabs (Registerkarten) auf material.io und Support different pixel densities (Unterstützung verschiedener Pixeldichten) auf developer.android.com. Weitere Informationen zum Verschieben der Registerkarten an den unteren Bildschirmrand finden Sie unter Setting TabbedPage Toolbar Placement and Color (Festlegen der TabbedPage-Symbolleistenanordnung und -farbe).
Auf der universellen Windows-Plattform (UWP) wird die Liste der Registerkarten am oberen Rand des Bildschirms angezeigt, und der Detailbereich befindet sich darunter. Jede Registerkarte umfasst einen Titel. Den Registerkarten können allerdings mit einem plattformspezifischen Element Symbole hinzugefügt werden. Weitere Informationen finden Sie unter TabbedPage Icons on Windows (TabbedPage-Symbole unter Windows).
Tipp
SVG-Dateien (skalierbare Vektorgrafik) können als Registerkartensymbole auf einem TabbedPage
-Element angezeigt werden:
- Die iOS-Klasse
TabbedRenderer
enthält eine überschreibbareGetIcon
-Methode, die verwendet werden kann, um Registerkartensymbole aus einer angegebenen Quelle zu laden. Darüber hinaus können die ausgewählten und nicht ausgewählten Versionen eines Symbols bei Bedarf zur Verfügung gestellt werden. - Die AppCompat-Klasse
TabbedPageRenderer
unter Android enthält eine überschreibbareSetTabIconImageSource
-Methode, die verwendet werden kann, um Registerkartensymbole aus einer benutzerdefiniertenDrawable
-Klasse zu laden. Alternativ dazu können SVG-Dateien in zeichenbare Vektorressourcen konvertiert werden, die automatisch von Xamarin.Forms angezeigt werden können. Weitere Informationen zum Konvertieren von SVG-Dateien in zeichenbare Vektorressourcen finden Sie auf „developer.android.com“ unter Add multi-density vector graphics (Hinzufügen von Vektorgrafiken mit mehreren Dichten).
Erstellen einer TabbedPage
Es gibt zwei Ansätze zum Erstellen einer TabbedPage
-Klasse:
- Füllen Sie die
TabbedPage
-Klasse mit einer Sammlung von untergeordnetenPage
-Objekten auf, z. B. einer Sammlung vonContentPage
-Objekten. Weitere Informationen finden Sie unter Populate a TabbedPage with a Page Collection (Füllen einer TabbedPage mit einer Seitensammlung). - Weisen Sie der
ItemsSource
-Eigenschaft eine Sammlung und derItemTemplate
-Eigenschaft eineDataTemplate
zu, um Seiten für Objekte in der Sammlung zurückzugeben. Weitere Informationen finden Sie unter Populate a TabbedPage with a template (Füllen einer TabbedPage mithilfe einer Vorlage).
Durch beide Ansätze zeigt die TabbedPage
-Klasse die entsprechende Seite an, wenn der Benutzer eine Registerkarte auswählt.
Wichtig
Es wird empfohlen, die TabbedPage
-Klasse nur mit NavigationPage
- und ContentPage
-Instanzen aufzufüllen. Dadurch wird eine konsistente Benutzerumgebung auf allen Plattformen gewährleistet.
Darüber hinaus definiert TabbedPage
die folgenden Eigenschaften:
BarBackgroundColor
vom TypColor
: die Hintergrundfarbe der RegisterkartenleisteBarTextColor
vom TypColor
: die Textfarbe auf der RegisterkartenleisteSelectedTabColor
vom TypColor
: die Registerkartenfarbe, wenn ausgewähltUnselectedTabColor
vom TypColor
: die Registerkartenfarbe, wenn nicht ausgewählt
Alle diese Eigenschaften werden durch BindableProperty
-Objekte gestützt, was bedeutet, dass die Eigenschaften formatiert werden können und die Ziele von Datenverbindungen sein können.
Warnung
In einer TabbedPage
wird jedes Page
-Objekt bei der Erstellung von TabbedPage
erstellt. Dies kann insbesondere dann das Benutzererlebnis beeinträchtigen, wenn die TabbedPage
die Stammseite der Anwendung ist. Die Xamarin.Forms-Shell ermöglicht es aber, dass Seiten, auf die über eine Registerkartenleiste zugegriffen wird, bei Bedarf als Reaktion auf die Navigation erstellt werden. Weitere Informationen finden Sie unter Xamarin.Forms-Shell.
Auffüllen einer TabbedPage mit einer Seitensammlung
Sie können eine TabbedPage
mit einer Sammlung von untergeordneten Page
-Objekten auffüllen, z. B. einer Sammlung von ContentPage
-Objekten. Dies wird erreicht, indem der TabbedPage.Children
-Sammlung die Page
-Objekte hinzugefügt werden. Dies kann in XAML folgendermaßen durchgeführt werden:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TabbedPageWithNavigationPage;assembly=TabbedPageWithNavigationPage"
x:Class="TabbedPageWithNavigationPage.MainPage">
<local:TodayPage />
<NavigationPage Title="Schedule" IconImageSource="schedule.png">
<x:Arguments>
<local:SchedulePage />
</x:Arguments>
</NavigationPage>
</TabbedPage>
Hinweis
Die Children
-Eigenschaft der MultiPage<T>
-Klasse, von der TabbedPage
abgeleitet ist, ist die ContentProperty
von MultiPage<T>
. Daher ist es in XAML nicht notwendig, die Page
-Objekte explizit der Children
-Eigenschaft zuzuweisen.
Der entsprechende C#-Code lautet:
public class MainPageCS : TabbedPage
{
public MainPageCS ()
{
NavigationPage navigationPage = new NavigationPage (new SchedulePageCS ());
navigationPage.IconImageSource = "schedule.png";
navigationPage.Title = "Schedule";
Children.Add (new TodayPageCS ());
Children.Add (navigationPage);
}
}
In diesem Beispiel wird die TabbedPage
mit zwei Page
-Objekten aufgefüllt. Beim ersten untergeordneten Objekt handelt es sich um ein ContentPage
-Objekt, und beim zweiten um eine NavigationPage
, die ein ContentPage
-Objekt enthält.
Die folgenden Screenshots zeigen ein ContentPage
-Objekt in einer TabbedPage
:
Durch das Auswählen einer anderen Registerkarte wird das ContentPage
-Objekt angezeigt, das die Registerkarte darstellt:
Auf der Registerkarte Schedule (Zeitplan) ist das ContentPage
-Objekt von einem NavigationPage
-Objekt umschlossen.
Warnung
Während eine NavigationPage
in eine TabbedPage
eingefügt werden kann, wird davon abgeraten, eine TabbedPage
in eine NavigationPage
einzufügen. Dies liegt darin begründet, dass UITabBarController
unter iOS immer als Wrapper für UINavigationController
fungiert. Weitere Informationen finden Sie unter Combined View Controller Interfaces (Kombinierte Schnittstellen für View Controller) in der iOS Developer Library.
Navigieren auf einer Registerkarte
Die Navigation kann auf einer Registerkarte ausgeführt werden, wenn das ContentPage
-Objekt von einem NavigationPage
-Objekt umschlossen wird. Dies wird durch die Aufrufen der PushAsync
-Methode in der Navigation
-Eigenschaft des ContentPage
-Objekts erreicht:
await Navigation.PushAsync (new UpcomingAppointmentsPage ());
Die Seite, die das Ziel der Navigation ist, wird der PushAsync
-Methode als Argument angegeben. In diesem Beispiel wird die Seite UpcomingAppointmentsPage
auf den Navigationsstapel gepusht und dort zur aktiven Seite:
Weitere Informationen zur Navigation mithilfe der NavigationPage
-Klasse finden Sie unter Hierarchical Navigation (Hierarchische Navigation).
Auffüllen einer TabbedPage mithilfe einer Vorlage
Eine TabbedPage
kann mit Seiten aufgefüllt werden, indem der ItemsSource
-Eigenschaft eine Sammlung von Daten zugewiesen wird. Dazu wird der ItemTemplate
-Eigenschaft eine DataTemplate
zugewiesen, die als Vorlage der Daten in Form von Page
-Objekten fungiert. Dies kann in XAML folgendermaßen durchgeführt werden:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TabbedPageDemo;assembly=TabbedPageDemo"
x:Class="TabbedPageDemo.TabbedPageDemoPage"
ItemsSource="{x:Static local:MonkeyDataModel.All}">
<TabbedPage.Resources>
<ResourceDictionary>
<local:NonNullToBooleanConverter x:Key="booleanConverter" />
</ResourceDictionary>
</TabbedPage.Resources>
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding Name}" IconImageSource="monkeyicon.png">
<StackLayout Padding="5, 25">
<Label Text="{Binding Name}" Font="Bold,Large" HorizontalOptions="Center" />
<Image Source="{Binding PhotoUrl}" WidthRequest="200" HeightRequest="200" />
<StackLayout Padding="50, 10">
<StackLayout Orientation="Horizontal">
<Label Text="Family:" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Family}" Font="Bold,Medium" />
</StackLayout>
...
</StackLayout>
</StackLayout>
</ContentPage>
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
Der entsprechende C#-Code lautet:
public class TabbedPageDemoPageCS : TabbedPage
{
public TabbedPageDemoPageCS ()
{
var booleanConverter = new NonNullToBooleanConverter ();
ItemTemplate = new DataTemplate (() =>
{
var nameLabel = new Label
{
FontSize = Device.GetNamedSize (NamedSize.Large, typeof(Label)),
FontAttributes = FontAttributes.Bold,
HorizontalOptions = LayoutOptions.Center
};
nameLabel.SetBinding (Label.TextProperty, "Name");
var image = new Image { WidthRequest = 200, HeightRequest = 200 };
image.SetBinding (Image.SourceProperty, "PhotoUrl");
var familyLabel = new Label
{
FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
FontAttributes = FontAttributes.Bold
};
familyLabel.SetBinding (Label.TextProperty, "Family");
...
var contentPage = new ContentPage
{
IconImageSource = "monkeyicon.png",
Content = new StackLayout {
Padding = new Thickness (5, 25),
Children =
{
nameLabel,
image,
new StackLayout
{
Padding = new Thickness (50, 10),
Children =
{
new StackLayout
{
Orientation = StackOrientation.Horizontal,
Children =
{
new Label { Text = "Family:", HorizontalOptions = LayoutOptions.FillAndExpand },
familyLabel
}
},
// ...
}
}
}
}
};
contentPage.SetBinding (TitleProperty, "Name");
return contentPage;
});
ItemsSource = MonkeyDataModel.All;
}
}
In diesem Beispiel enthält jede Registerkarte ein ContentPage
-Objekt, das Image
-Objekte und Label
-Objekte für das Anzeigen von Daten für die Registerkarte verwendet:
Durch das Auswählen einer anderen Registerkarte wird das ContentPage
-Objekt angezeigt, das die Registerkarte darstellt.