Qual è la differenza tra LayoutOptions di Xamarin.Form, in particolare Fill ed Expand?


170

In Xamarin.Forms ognuno Viewha le due proprietà HorizontalOptionse VerticalOptions. Entrambi sono di tipo LayoutOptionse possono avere uno dei seguenti valori:

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill
  • LayoutOptions.StartAndExpand
  • LayoutOptions.CenterAndExpand
  • LayoutOptions.EndAndExpand
  • LayoutOptions.FillAndExpand

Apparentemente controlla l'allineamento della vista sulla vista principale. Ma com'è esattamente il comportamento di ogni singola opzione? E qual è la differenza tra Fille il suffisso Expand?

Risposte:


335

Risposta breve

Start, Center, EndE Filldefinire della visualizzazione allineamento nel suo spazio .

Expanddefinisce se occupa più spazio se disponibile.

Teoria

La struttura LayoutOptionscontrolla due comportamenti distinti:

  1. Allineamento: come viene allineata la vista all'interno della vista principale?

    • Start: Per l'allineamento verticale la vista viene spostata verso l'alto. Per l'allineamento orizzontale questo è generalmente il lato sinistro. (Si noti, tuttavia, che sui dispositivi con impostazione della lingua da destra a sinistra è il contrario, ovvero allineato a destra.)
    • Center: La vista è centrata.
    • End: Di solito la vista è allineata in basso o a destra. (Nelle lingue da destra a sinistra, ovviamente, allineato a sinistra.)
    • Fill: Questo allineamento è leggermente diverso. La vista si estenderà per l'intera dimensione della vista padre.

    Se il genitore, tuttavia, non è più grande dei suoi figli, non noterai alcuna differenza tra questi allineamenti. L'allineamento è importante solo per le viste principali con spazio aggiuntivo disponibile.

  2. Espansione: l'elemento occuperà più spazio se disponibile?

    • Suffisso Expand: se la vista padre è più grande della dimensione combinata di tutti i suoi figli, ovvero è disponibile spazio aggiuntivo, allora lo spazio viene proporzionato tra le viste figlio con quel suffisso. Quei bambini "occuperanno" il loro spazio, ma non necessariamente lo "riempiranno". Daremo un'occhiata a questo comportamento nell'esempio seguente.
    • Nessun suffisso: i bambini senza Expandsuffisso non avranno spazio aggiuntivo, anche se è disponibile più spazio.

    Ancora una volta, se la vista padre non è più grande dei suoi figli, anche il suffisso di espansione non fa alcuna differenza.

Esempio

Diamo un'occhiata al seguente esempio per vedere la differenza tra tutte e otto le opzioni di layout.

L'app contiene un grigio scuro StackLayoutcon otto pulsanti bianchi nidificati, ognuno dei quali è etichettato con la sua opzione di layout verticale. Facendo clic su uno dei pulsanti, assegna la sua opzione di layout verticale al layout dello stack. In questo modo possiamo facilmente testare l'interazione delle viste con i genitori, entrambe con diverse opzioni di layout.

(Le ultime righe di codice aggiungono ulteriori caselle gialle. Torneremo su questo tra un momento.)

public static class App
{
    static readonly StackLayout stackLayout = new StackLayout {
        BackgroundColor = Color.Gray,
        VerticalOptions = LayoutOptions.Start,
        Spacing = 2,
        Padding = 2,
    };

    public static Page GetMainPage()
    {
        AddButton("Start", LayoutOptions.Start);
        AddButton("Center", LayoutOptions.Center);
        AddButton("End", LayoutOptions.End);
        AddButton("Fill", LayoutOptions.Fill);
        AddButton("StartAndExpand", LayoutOptions.StartAndExpand);
        AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand);
        AddButton("EndAndExpand", LayoutOptions.EndAndExpand);
        AddButton("FillAndExpand", LayoutOptions.FillAndExpand);

        return new NavigationPage(new ContentPage {
            Content = stackLayout,
        });
    }

    static void AddButton(string text, LayoutOptions verticalOptions)
    {
        stackLayout.Children.Add(new Button {
            Text = text,
            BackgroundColor = Color.White,
            VerticalOptions = verticalOptions,
            HeightRequest = 20,
            Command = new Command(() => {
                stackLayout.VerticalOptions = verticalOptions;
                (stackLayout.ParentView as Page).Title = "StackLayout: " + text;
            }),
        });
        stackLayout.Children.Add(new BoxView {
            HeightRequest = 1,
            Color = Color.Yellow,
        });
    }
}

Le seguenti schermate mostrano il risultato quando si fa clic su ciascuno degli otto pulsanti. Facciamo le seguenti osservazioni:

  • Finché il genitore stackLayoutè stretto (non Fillla pagina), l'opzione di layout verticale di ciascuno Buttonè trascurabile.
  • L'opzione di layout verticale è importante solo se stackLayoutè più grande (ad es. Tramite Fillallineamento) e i singoli pulsanti hanno il Expandsuffisso.
  • Lo spazio aggiuntivo viene eventualmente proporzionato tra tutti i pulsanti con Expandsuffisso. Per vederlo più chiaramente, abbiamo aggiunto delle linee orizzontali gialle tra ogni due pulsanti vicini.
  • I pulsanti con più spazio rispetto all'altezza richiesta non necessariamente lo "riempiono". In questo caso il comportamento effettivo è controllato dal loro allineamento. Ad esempio, sono allineati in alto, al centro o al pulsante del loro spazio o lo riempiono completamente.
  • Tutti i pulsanti si estendono su tutta la larghezza del layout, poiché modifichiamo solo VerticalOptions.

Screenshots

Qui trovi gli screenshot ad alta risoluzione corrispondenti.


6
l'immagine appare come [[midfing]], lol. scherzare è stato davvero utile
Joy Rex,

1
@JoyRex: Beh, forse questa versione è un po 'meno confusa. ;)
Falko,

2
Ho confuso con l'output sopra. start & startAndExpand entrambi sono lo stesso output. Qual è la differenza tra questi? puoi dare una spiegazione se possibile ..
Ranjith Kumar,

1
FillAndExpandè quello che vuoi, il 99% delle volte
Stephane Delcroix il

1
@RanjithKumar Sono gli stessi. StackLayout è stato nidificato in un altro genitore, quindi FillAndExpand potrebbe fare la differenza: si espanderebbe all'interno del suo genitore.
Miha Markic,

16

C'è un po 'di bug nella versione corrente di Xamarin.Forms; forse è stato lì un po '.

CenterAndExpand generalmente non si espande e aggirarlo può creare confusione.

Ad esempio, se si dispone di un StackLayoutset per CenterAndExpand, quindi si inserisce un'etichetta all'interno di quello impostato su di CenterAndExpandte, ci si aspetterebbe un'etichetta che è la larghezza completa di StackLayout. No. Non si espanderà. Devi impostare StackLayout" FillAndExpand" per fare in modo che l'oggetto Label nidificato si espanda alla larghezza completa di StackLayout, quindi indica a Label di centrare il testo, non se stesso come oggetto, con HorizontalTextAlignment="Center". Nella mia esperienza hai bisogno di impostare sia il genitore che il figlio nidificato FillAndExpandse vuoi davvero assicurarti che si espanda per adattarsi.

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />

3
"... ti aspetteresti un'etichetta che sia tutta la larghezza di StackLayout." Questo presupposto non è corretto. Expandviene utilizzato solo per i bambini di StackLayout. Quindi, se StackLayout è il root, o no in un altro StackLayout, Expandnon ha alcun effetto. Invece, qualsiasi opzione diversa da Fill fungerebbe da "contenuto a capo" per il dimensionamento, che è quello che vedi.
therealjohn,

Inoltre, l'espansione funziona solo per LayoutOptions che hanno lo stesso orientamento di StackLayout. In questo caso, il layout è "Verticale", ma le opzioni in questione sono Orizzontale (opposti).
therealjohn,

Il termine "AndExpand" è ambiguo. Potrebbe essere interpretato come "espandi il più possibile" o "espandi solo il necessario". Penso che Microsoft dovrebbe cambiare i termini in qualcosa di meno confuso, come "CenterAndExpandToParent" o "CenterAndExpandAsNeeded"
technoman23

1

Falko ha dato una buona spiegazione, ma volevo aggiungerlo con un altro aspetto visivo e come funzionano questi tag in xaml, che è ciò che preferisco usare la maggior parte delle volte. Ho realizzato un semplice progetto per testare i risultati di visualizzazione. Ecco lo Xaml per la pagina principale:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Alignments.MainPage"
             BackgroundColor="White">


    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="1" Margin="30">
        <Label Text="Vert: EndAndExpand, Horz: EndAndExpand" VerticalOptions="EndAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="White"/>
    </StackLayout>


</ContentPage>

Come puoi vedere è un StackLayout molto semplice con all'interno un'etichetta. Per ogni immagine in basso ho mantenuto StackLayout lo stesso, ho appena cambiato le opzioni orizzontali e verticali per la voce e modificato il testo per mostrare le opzioni selezionate, in modo da poter vedere come la voce si sposta e ridimensiona.

Start vs StartAndExpand Ecco il codice utilizzato per Start:

<Label Text="Vert: Start, Horz: Start" VerticalOptions="Start" HorizontalOptions="Start" BackgroundColor="White"/>

E il codice utilizzato per StartAndExpand:

<Label Text="Vert: StartAndExpand, Horz: StartAndExpand" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" BackgroundColor="White"/>

Come puoi vedere, non c'è alcuna differenza visiva se non che c'è più testo usato nell'opzione StartAndExpand. Questo è stato testato sul mio dispositivo fisico Samsung A30. Questi possono essere visualizzati in modo diverso su dispositivi diversi, ma penso che tutte le immagini qui mostrino collettivamente che ci sono alcuni bug in Xamarin. Per il resto mostrerò solo gli screenshot, penso che siano autoesplicativi.

End vs EndAndExpand

Center vs CenterAndExpand

Fill vs FillAndExpand

Consiglio anche di dare un'occhiata alla documentazione di Microsoft per alcuni dettagli aggiuntivi. Notevole è che "L'espansione è utilizzata solo da uno StackLayout".


Bella visualizzazione. Ma non vedo perché questo dovrebbe mostrare bug in Xamarin. Ciò che potrebbe creare confusione è che le etichette possono occupare più spazio del loro sfondo bianco (le aree grigie nel mio esempio). Quindi un'etichetta "Vert Center" è centrata nello spazio che occupa, non nell'intera pagina. Apparentemente, dopo quasi sei anni questo argomento è ancora confuso come lo era di nuovo.
Falko,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.