Xamarin.Forms Riquadro a comparsa

Download Sample Scaricare l'esempio

Una pagina a comparsa visualizza in genere un elenco di elementi, come illustrato negli screenshot seguenti:

Flyout Page Components

La posizione dell'elenco di elementi è identica in ogni piattaforma e la selezione di uno degli elementi consente di passare alla pagina di dettaglio corrispondente. Inoltre, la pagina a comparsa include anche una barra di spostamento che contiene un pulsante che può essere usato per passare alla pagina dei dettagli attiva:

  • In iOS la barra di navigazione si trova nella parte superiore della pagina e include un pulsante che consente di passare alla pagina di dettaglio. Inoltre, è possibile passare alla pagina dei dettagli attiva facendo clic sul riquadro a comparsa a sinistra.
  • In Android la barra di navigazione si trova nella parte superiore della pagina e visualizza un titolo, un'icona e un pulsante che consente di passare alla pagina di dettaglio. L'icona è definita nell'attributo [Activity] che decora la classe MainActivity nel progetto specifico della piattaforma Android. Inoltre, la pagina dei dettagli attiva può essere spostata facendo clic sul riquadro a comparsa a sinistra, toccando la pagina dei dettagli all'estrema destra dello schermo e toccando il pulsante Indietro nella parte inferiore dello schermo.
  • Nella piattaforma UWP (Universal Windows Platform) la barra di navigazione si trova nella parte superiore della pagina e include un pulsante che consente di passare alla pagina di dettaglio.

In una pagina dei dettagli vengono visualizzati i dati corrispondenti all'elemento selezionato nella pagina a comparsa e i componenti principali della pagina dei dettagli sono illustrati negli screenshot seguenti:

Detail Page Components

La pagina di dettaglio contiene una barra di navigazione il cui contenuto dipende dalla piattaforma:

  • In iOS, la barra di spostamento è presente nella parte superiore della pagina e visualizza un titolo e ha un pulsante che torna alla pagina a comparsa, purché l'istanza della pagina dei dettagli sia inclusa nell'istanza NavigationPage . Inoltre, la pagina a comparsa può essere restituita facendo scorrere la pagina dei dettagli a destra.
  • In Android, una barra di spostamento è presente nella parte superiore della pagina e visualizza un titolo, un'icona e un pulsante che torna alla pagina a comparsa. L'icona è definita nell'attributo [Activity] che decora la classe MainActivity nel progetto specifico della piattaforma Android.
  • Nella piattaforma UWP la barra di spostamento è presente nella parte superiore della pagina e visualizza un titolo e ha un pulsante che torna alla pagina a comparsa.

Il comportamento dell'esperienza di spostamento tra il riquadro a comparsa e le pagine di dettaglio dipende dalla piattaforma:

  • In iOS la pagina dei dettagli scorre verso destra mentre la pagina a comparsa scorre da sinistra e la parte sinistra della pagina dei dettagli è ancora visibile.
  • In Android, le pagine di dettaglio e riquadro a comparsa sono sovrapposte l'una all'altra.
  • Nella piattaforma UWP la pagina a comparsa scorre dalla parte sinistra della pagina dei dettagli, purché la FlyoutLayoutBehavior proprietà sia impostata su Popover.

Un comportamento simile verrà osservato in modalità orizzontale, ad eccezione del fatto che la pagina a comparsa in iOS e Android ha una larghezza simile a quella della pagina a comparsa in modalità verticale, quindi più della pagina dei dettagli sarà visibile.

Per informazioni sul controllo del comportamento di spostamento, vedere Controllare il comportamento del layout della pagina dei dettagli.

Creare un riquadro a comparsa

Un FlyoutPage oggetto contiene Flyout e Detail proprietà che sono entrambi di tipo Page, che vengono usati rispettivamente per ottenere e impostare il riquadro a comparsa e le pagine di dettaglio.

Importante

Una FlyoutPage è progettata per essere una pagina radice e l'uso come pagina figlio in altri tipi di pagina può determinare un comportamento imprevisto e incoerente. È inoltre consigliabile che la pagina del riquadro a comparsa di un oggetto FlyoutPage sia sempre un'istanza ContentPage e che la pagina dei dettagli debba essere popolata solo con TabbedPageistanze , NavigationPagee ContentPage . In questo modo si potrà garantire un'esperienza utente uniforme su tutte le piattaforme.

L'esempio di codice XAML seguente illustra una FlyoutPage che imposta le proprietà Flyout e Detail:

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

L'esempio di codice seguente illustra la FlyoutPage equivalente creata in C#:

public class MainPageCS : FlyoutPage
{
    FlyoutMenuPageCS flyoutPage;

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

La proprietà Flyout viene impostata su un'istanza di ContentPage. La proprietà Detail viene impostata su una classe NavigationPage contenente un'istanza di ContentPage.

Creare la pagina a comparsa

L'esempio di codice XAML seguente illustra la dichiarazione dell'oggetto FlyoutMenuPage a cui si fa riferimento tramite la proprietà Flyout:

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

La pagina è costituita da un ListView oggetto popolato con dati in XAML impostandone la ItemsSource proprietà su una matrice di FlyoutPageItem oggetti. Ogni FlyoutPageItem definisce le proprietà Title, IconSource e TargetType.

Una classe DataTemplate è assegnata alla proprietà ListView.ItemTemplate per visualizzare ogni FlyoutPageItem. DataTemplate contiene una classe ViewCell composta da una classe Image e una classe Label. Image visualizza il valore della proprietà IconSource e Label visualizza il valore della proprietà Title per ogni FlyoutPageItem.

La pagina ha le proprietà Title e IconImageSource impostate. L'icona verrà visualizzata nella pagina di dettaglio a condizione che in quest'ultima sia presente una barra del titolo. È necessario abilitare questa funzionalità in iOS eseguendo il wrapping dell'istanza della pagina di dettaglio in un'istanza di NavigationPage.

Nota

La pagina Flyout deve avere la proprietà Title impostata. In caso contrario, verrà generata un'eccezione.

L'esempio di codice seguente illustra la pagina equivalente creata in C#:

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

Gli screenshot seguenti mostrano la pagina del riquadro a comparsa in ogni piattaforma:

Flyout Page Example

Creare e visualizzare la pagina dei dettagli

L'istanza di FlyoutMenuPage contiene una proprietà ListView che espone l'istanza di ListView in modo che l'istanza MainPageFlyoutPage possa registrare un gestore eventi per la gestione dell'evento ItemSelected. Ciò consente all'istanza di MainPage di impostare la proprietà Detail sulla pagina che rappresenta l'elemento ListView selezionato. L'esempio di codice seguente illustra il gestore eventi:

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

Il metodo OnItemSelected esegue le azioni seguenti:

  • Recupera SelectedItem dall'istanza di ListView e, a condizione che non sia null, imposta la pagina di dettaglio su una nuova istanza del tipo di pagina archiviato nella proprietà TargetType di FlyoutPageItem. Viene eseguito il wrapping del tipo di pagina in un'istanza di NavigationPage per assicurarsi che l'icona a cui si fa riferimento tramite la proprietà IconImageSource in FlyoutMenuPage venga visualizzata nella pagina di dettaglio in iOS.
  • L'elemento selezionato in ListView viene impostato su null per assicurarsi che nessuno degli elementi ListView verrà selezionato alla successiva visualizzazione di FlyoutMenuPage.
  • La pagina di dettaglio viene presentata all'utente impostando la proprietà FlyoutPage.IsPresented su false. Questa proprietà controlla se viene visualizzata la pagina a comparsa o di dettaglio. Deve essere impostato su true per visualizzare la pagina a comparsa e per false visualizzare la pagina dei dettagli.

Gli screenshot seguenti mostrano la ContactPage pagina dei dettagli, visualizzata dopo che è stata selezionata nella pagina a comparsa:

Detail Page Example

Controllare il comportamento del layout della pagina dei dettagli

Il modo FlyoutPage in cui gestisce il riquadro a comparsa e le pagine di dettaglio dipende dal fatto che l'applicazione sia in esecuzione su un telefono o un tablet, l'orientamento del dispositivo e il valore della FlyoutLayoutBehavior proprietà. Questa proprietà determina il modo in cui verrà visualizzata la pagina di dettaglio. I valori possibili sono:

  • Default : le pagine vengono visualizzate usando l'impostazione predefinita della piattaforma.
  • Popover : la pagina dei dettagli copre o copre parzialmente la pagina del riquadro a comparsa.
  • Split : la pagina a comparsa viene visualizzata a sinistra e la pagina dei dettagli si trova a destra.
  • SplitOnLandscape : viene usata una schermata divisa quando il dispositivo è in orientamento orizzontale.
  • SplitOnPortrait : viene usata una schermata divisa quando il dispositivo è in orientamento verticale.

L'esempio di codice XAML seguente illustra come impostare la proprietà FlyoutLayoutBehavior in una FlyoutPage:

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

L'esempio di codice seguente illustra la FlyoutPage equivalente creata in C#:

public class MainPageCS : FlyoutPage
{
    FlyoutMenuPageCS flyoutPage;

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

Importante

Il valore della FlyoutLayoutBehavior proprietà influisce solo sulle applicazioni in esecuzione su tablet o desktop. Le applicazioni in esecuzione sui telefoni hanno sempre il Popover comportamento.