Xamarin.Forms FlyoutPage

Download Sample Das Beispiel herunterladen

In der Regel zeigt eine Flyout-Seite wie in den folgenden Screenshots gezeigt eine Liste von Elementen an:

Flyout Page Components

Der Speicherort für die Liste der Elemente ist auf jeder Plattform identisch. Wenn Sie eines der Elemente auswählen, wird zur entsprechenden Detailseite navigiert. Darüber hinaus verfügt die Flyout-Seite auch über eine Navigationsleiste, die eine Schaltfläche enthält, mit der Sie zur aktiven Detailseite navigieren können:

  • Unter iOS finden Sie die Navigationsleiste am oberen Rand der Seite, und sie verfügt über eine Schaltfläche, mit der zur Detailseite navigiert werden kann. Sie können außerdem zur aktiven Detailseite navigieren, indem Sie das Flyout nach links wischen.
  • Unter Android finden Sie die Navigationsleiste ebenfalls am oberen Rand der Seite, und sie zeigt einen Titel, ein Symbol und eine Schaltfläche an, mit der zur Detailseite navigiert werden kann. Das Symbol wird im [Activity]-Attribut definiert, das die MainActivity-Klasse im plattformspezifischen Android-Projekt ergänzt. Darüber hinaus können Sie zur aktiven Detailseite navigieren, indem Sie auf der Flyout-Seite nach links wischen, auf der rechten Seite des Bildschirms auf die Detailseite tippen oder am unteren Rand des Bildschirms auf Zurück tippen.
  • Bei der UWP (Universelle Windows-Plattform) finden Sie die Navigationsleiste am oberen Rand der Seite, und sie verfügt über eine Schaltfläche, mit der zur Detailseite navigiert werden kann.

Auf einer Detailseite werden Daten angezeigt, die dem auf der Flyout-Seite ausgewählten Element entsprechen. In den folgenden Screenshots sehen Sie die Hauptkomponenten der Detailseite:

Detail Page Components

Die Detailseite enthält eine Navigationsleiste, deren Inhalt von der jeweiligen Plattform abhängen:

  • Unter iOS finden Sie die Navigationsleiste am oberen Rand der Seite. Dort werden ein Titel und eine Schaltfläche angezeigt, mit der zur Flyout-Seite zurück navigiert werden kann, vorausgesetzt, die Detailseiteninstanz ist in der NavigationPage-Instanz umschlossen. Sie können außerdem zur Flyout-Seite zurückkehren, indem Sie auf der Detailseite nach rechts wischen.
  • Unter Android finden Sie die Navigationsleiste ebenfalls am oberen Rand der Seite, und sie zeigt einen Titel, ein Symbol und eine Schaltfläche an, mit der zurück zur Flyout-Seite navigiert werden kann. Das Symbol wird im [Activity]-Attribut definiert, das die MainActivity-Klasse im plattformspezifischen Android-Projekt ergänzt.
  • Bei der UWP finden Sie die Navigationsleiste ebenfalls am oberen Rand der Seite, und sie zeigt einen Titel, ein Symbol und eine Schaltfläche an, mit der zurück zur Flyout-Seite navigiert werden kann.

Das Verhalten der Navigationsfunktion zwischen Flyout-Seiten und Detailseiten ist plattformabhängig:

  • Unter iOS können Sie die Detailseite nach rechts und die Flyout-Seite nach links schieben, und der linke Teil der Detailseite bleibt weiterhin sichtbar.
  • Unter Android werden die Detailseiten und Flyout-Seiten miteinander überlagert.
  • Auf der Universellen Windows-Plattform werden Flyout-Seiten von der linken Seite aus eingeblendet und bedecken die Detailseite teilweise, sofern die Eigenschaft FlyoutLayoutBehavior auf Popover festgelegt ist.

Im Querformat wird ein ähnliches Verhalten angewandt, mit der Ausnahme, dass die Flyout-Seite unter iOS und Android eine ähnliche Breite wie die Flyout-Seite im Hochformat aufweist, weshalb mehr von der Detailseite angezeigt wird.

Informationen zum Steuern des Navigationsverhaltens finden Sie unter Steuern des Layoutverhaltens der Detailseite.

Erstellen einer FlyoutPage-Klasse

Eine FlyoutPage-Klasse enthält die Eigenschaften Flyout und Detail vom Typ Page, die beide jeweils dazu verwendet werden, die Flyout-Seiten und Detailseiten abzurufen und festzulegen.

Wichtig

Eine FlyoutPage-Klasse fungiert als Stammseite. Wenn Sie sie für andere Seitentypen als untergeordnete Seite verwenden, kann dies zu unerwartetem und inkonsistentem Verhalten führen. Darüber hinaus wird empfohlen, dass die Flyoutseite einer Instanz FlyoutPage immer eine ContentPage Instanz sein sollte und dass die Detailseite nur mit TabbedPage, NavigationPageund ContentPage Instanzen gefüllt werden sollte. Dadurch wird eine konsistente Benutzerumgebung auf allen Plattformen gewährleistet.

Im folgenden XAML-Codebeispiel wird eine FlyoutPage-Klasse veranschaulicht, die die Eigenschaften Flyout und Detail festlegt:

<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:FlyoutPageNavigation;assembly=FlyoutPageNavigation"
            x:Class="FlyoutPageNavigation.MainPage">
    <FlyoutPage.Flyout>
        <local:FlyoutMenuPage x:Name="flyoutPage" />
    </FlyoutPage.Flyout>
    <FlyoutPage.Detail>
        <NavigationPage>
            <x:Arguments>
                <local:ContactsPage />
            </x:Arguments>
        </NavigationPage>
    </FlyoutPage.Detail>
</FlyoutPage>

Im folgenden Codebeispiel wird die entsprechende FlyoutPage-Klasse in C# dargestellt:

public class MainPageCS : FlyoutPage
{
    FlyoutMenuPageCS flyoutPage;

    public MainPageCS()
    {
        flyoutPage = new FlyoutMenuPageCS();
        Flyout = flyoutPage;
        Detail = new NavigationPage(new ContactsPageCS());
        ...
    }
    ...
}    

Die Flyout-Eigenschaft wird auf eine ContentPage-Instanz festgelegt. Die Detail-Eigenschaft wird auf eine NavigationPage-Klasse festgelegt, die eine ContentPage-Instanz enthält.

Erstellen der Flyout-Seite

Im folgenden XAML-Codebeispiel wird die Deklaration des FlyoutMenuPage-Objekts gezeigt, auf das von der Flyout-Eigenschaft verwiesen wird:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="using:FlyoutPageNavigation"
             x:Class="FlyoutPageNavigation.FlyoutMenuPage"
             Padding="0,40,0,0"
             IconImageSource="hamburger.png"
             Title="Personal Organiser">
    <StackLayout>
        <ListView x:Name="listView" x:FieldModifier="public">
            <ListView.ItemsSource>
                <x:Array Type="{x:Type local:FlyoutPageItem}">
                    <local:FlyoutPageItem Title="Contacts" IconSource="contacts.png" TargetType="{x:Type local:ContactsPage}" />
                    <local:FlyoutPageItem Title="TodoList" IconSource="todo.png" TargetType="{x:Type local:TodoListPage}" />
                    <local:FlyoutPageItem Title="Reminders" IconSource="reminders.png" TargetType="{x:Type local:ReminderPage}" />
                </x:Array>
            </ListView.ItemsSource>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid Padding="5,10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="30"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Image Source="{Binding IconSource}" />
                            <Label Grid.Column="1" Text="{Binding Title}" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Die Seite besteht aus einer ListView-Klasse, die in XAML mit Daten gefüllt wird, indem ihre ItemsSource-Eigenschaft auf ein Array von FlyoutPageItem-Objekten festgelegt wird. Jede FlyoutPageItem-Instanz definiert die Eigenschaften Title, IconSource und TargetType.

Der Eigenschaft ListView.ItemTemplate wird eine DataTemplate-Klasse zugewiesen, um alle FlyoutPageItem-Instanzen anzuzeigen. Die DataTemplate-Klasse enthält eine ViewCell-Klasse, die aus den Klassen Image und Label besteht. Für jede FlyoutPageItem-Instanz zeigt die Image-Klasse den Eigenschaftswert IconSource und die Label-Klasse den Eigenschaftswert Title an.

Die Title- und IconImageSource-Eigenschaften der Seite sind festgelegt. Das Symbol wird auf der Detailseite angezeigt, wenn sie über eine Titelleiste verfügt. Unter iOS muss dies aktiviert werden, indem Sie die Detailseiteninstanz mit einer NavigationPage-Instanz umschließen.

Hinweis

Die Title-Eigenschaft der Flyout-Seite muss festgelegt sein, da sonst eine Ausnahme ausgelöst wird.

Im folgenden Codebeispiel wird die Erstellung der entsprechenden Seite in C# dargestellt:

public class FlyoutMenuPageCS : ContentPage
{
    ListView listView;
    public ListView ListView { get { return listView; } }

    public FlyoutMenuPageCS()
    {
        var flyoutPageItems = new List<FlyoutPageItem>();
        flyoutPageItems.Add(new FlyoutPageItem
        {
            Title = "Contacts",
            IconSource = "contacts.png",
            TargetType = typeof(ContactsPageCS)
        });
        flyoutPageItems.Add(new FlyoutPageItem
        {
            Title = "TodoList",
            IconSource = "todo.png",
            TargetType = typeof(TodoListPageCS)
        });
        flyoutPageItems.Add(new FlyoutPageItem
        {
            Title = "Reminders",
            IconSource = "reminders.png",
            TargetType = typeof(ReminderPageCS)
        });

        listView = new ListView
        {
            ItemsSource = flyoutPageItems,
            ItemTemplate = new DataTemplate(() =>
            {
                var grid = new Grid { Padding = new Thickness(5, 10) };
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });

                var image = new Image();
                image.SetBinding(Image.SourceProperty, "IconSource");
                var label = new Label { VerticalOptions = LayoutOptions.FillAndExpand };
                label.SetBinding(Label.TextProperty, "Title");

                grid.Children.Add(image);
                grid.Children.Add(label, 1, 0);

                return new ViewCell { View = grid };
            }),
            SeparatorVisibility = SeparatorVisibility.None
        };

        IconImageSource = "hamburger.png";
        Title = "Personal Organiser";
        Padding = new Thickness(0, 40, 0, 0);
        Content = new StackLayout
        {
            Children = { listView }
        };
    }
}

In den folgenden Screenshots wird die Flyout-Seite auf den jeweiligen Plattformen veranschaulicht:

Flyout Page Example

Erstellen und Anzeigen der Detailseite

Die FlyoutMenuPage Instanz enthält eine ListView Eigenschaft, die seine ListView Instanz verfügbar macht, damit die MainPageFlyoutPage Instanz einen Ereignishandler registrieren kann, um das ItemSelected Ereignis zu behandeln. Dies ermöglicht der MainPage-Instanz, die Detail-Eigenschaft auf die Seite festzulegen, die das ausgewählte ListView-Element darstellt. Im folgenden Codebeispiel wird der Ereignishandler gezeigt:

public partial class MainPage : FlyoutPage
{
    public MainPage()
    {
        ...
        flyoutPage.listView.ItemSelected += OnItemSelected;
    }

    void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        var item = e.SelectedItem as FlyoutPageItem;
        if (item != null)
        {
            Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType));
            flyoutPage.listView.SelectedItem = null;
            IsPresented = false;
        }
    }
}

Die OnItemSelected-Methode führt die folgenden Aktionen aus:

  • Sofern sie nicht den Wert aufweist, ruft sie das SelectedItem-Element aus der nullListView-Instanz ab und legt die Detailseite auf eine neue Instanz des Seitentyps fest, der in der TargetType-Eigenschaft der FlyoutPageItem-Klasse enthalten ist. Der Seitentyp wird in einer NavigationPage-Instanz umschlossen, um sicherzustellen, dass das Symbol, auf das mit der IconImageSource-Eigenschaft von FlyoutMenuPage verwiesen wird, unter iOS auf der Detailseite angezeigt wird.
  • Für das in der ListView-Klasse ausgewählte Element wird null festgelegt, um sicherzustellen, dass keines der ListView-Elemente beim nächsten Mal ausgewählt wird, wenn FlyoutMenuPage angezeigt wird.
  • Die Detailseite wird dem Benutzer angezeigt, indem die FlyoutPage.IsPresented-Eigenschaft auf false festgelegt wird. Diese Eigenschaft steuert, ob die Flyout-Seite oder die Detailseite angezeigt wird. Sie sollte auf true festgelegt werden, um die Flyout-Seite anzuzeigen, oder auf false, um die Detailseite anzuzeigen.

In den folgenden Screenshots wird die Detailseite ContactPage gezeigt, die angezeigt wird, wenn sie auf der Flyout-Seite ausgewählt wurde:

Detail Page Example

Steuern des Layoutverhaltens der Detailseite

Wie die FlyoutPage-Klasse die Flyout-Seiten und Detailseiten verwaltet hängt davon ab, ob die Anwendung auf einem Smartphone oder Tablet ausgeführt wird, wie das Gerät ausgerichtet ist und welchen Wert die FlyoutLayoutBehavior-Eigenschaft aufweist. Diese Eigenschaft bestimmt, wie die Detailseite angezeigt wird. Folgende Werte sind möglich:

  • Default Die Seiten werden gemäß des plattformspezifischen Standards angezeigt.
  • Popover: Die Detailseite deckt die Flyout-Seite vollständig ab oder deckt sie teilweise ab.
  • Split: Die Flyout-Seite wird auf der linken Seite angezeigt und die Detailseite auf der rechten.
  • SplitOnLandscape Wenn das Gerät sich im Querformat befindet, wird der Bildschirm mittels Bildschirmaufteilung aufgeteilt.
  • SplitOnPortrait Wenn das Gerät sich im Hochformat befindet, wird der Bildschirm mittels Bildschirmaufteilung aufgeteilt.

Im folgenden XAML-Codebeispiel wird gezeigt, wie die FlyoutLayoutBehavior-Eigenschaft einer FlyoutPage-Klasse festgelegt wird:

<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="FlyoutPageNavigation.MainPage"
            FlyoutLayoutBehavior="Popover">
  ...
</FlyoutPage>

Im folgenden Codebeispiel wird die entsprechende FlyoutPage-Klasse in C# dargestellt:

public class MainPageCS : FlyoutPage
{
    FlyoutMenuPageCS flyoutPage;

    public MainPageCS()
    {
        ...
        FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
    }
}

Wichtig

Der Wert der FlyoutLayoutBehavior-Eigenschaft wirkt sich nur auf Anwendungen aus, die auf einem Tablet oder Desktop ausgeführt werden. Anwendungen, die auf Smartphones ausgeführt werden, weisen immer das Verhalten Popover auf.