Was ist der Unterschied zwischen den LayoutOptions von Xamarin.Form, insbesondere Füllen und Erweitern?

170

In Xamarin.Forms hat jeder Viewdie beiden Eigenschaften HorizontalOptionsund VerticalOptions. Beide sind vom Typ LayoutOptionsund können einen der folgenden Werte haben:

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

Anscheinend steuert es die Ausrichtung der Ansicht in der übergeordneten Ansicht. Aber wie genau ist das Verhalten jeder einzelnen Option? Und was ist der Unterschied zwischen Fillund dem Suffix Expand?

Falko
quelle

Antworten:

335

Kurze Antwort

Start, Center, EndUnd Filldie Ansicht definieren Ausrichtung innerhalb seines Raumes .

Expanddefiniert, ob es mehr Platz einnimmt, falls verfügbar.

Theorie

Die Struktur LayoutOptionssteuert zwei unterschiedliche Verhaltensweisen:

  1. Ausrichtung: Wie ist die Ansicht in der übergeordneten Ansicht ausgerichtet?

    • Start: Zur vertikalen Ausrichtung wird die Ansicht nach oben verschoben. Bei horizontaler Ausrichtung ist dies normalerweise die linke Seite. (Beachten Sie jedoch, dass dies bei Geräten mit einer Spracheinstellung von rechts nach links umgekehrt ist, dh rechtsbündig.)
    • Center: Die Ansicht ist zentriert.
    • End: Normalerweise ist die Ansicht unten oder rechts ausgerichtet. (Bei Sprachen von rechts nach links natürlich linksbündig.)
    • Fill: Diese Ausrichtung ist etwas anders. Die Ansicht erstreckt sich über die gesamte Größe der übergeordneten Ansicht.

    Wenn das übergeordnete Element jedoch nicht größer als die untergeordneten Elemente ist, werden Sie keinen Unterschied zwischen diesen Ausrichtungen feststellen. Die Ausrichtung ist nur für übergeordnete Ansichten mit zusätzlichem verfügbaren Speicherplatz von Bedeutung.

  2. Erweiterung: Wird das Element mehr Platz einnehmen, falls verfügbar?

    • Suffix Expand : Wenn die übergeordnete Ansicht größer ist als die kombinierte Größe aller untergeordneten Ansichten, dh zusätzlicher Speicherplatz verfügbar ist, wird der Speicherplatz unter den untergeordneten Ansichten mit diesem Suffix aufgeteilt. Diese Kinder "besetzen" ihren Raum, "füllen" ihn aber nicht unbedingt. Wir werden uns dieses Verhalten im folgenden Beispiel ansehen.
    • Kein Suffix: Die Kinder ohne ExpandSuffix erhalten keinen zusätzlichen Speicherplatz, selbst wenn mehr Speicherplatz verfügbar ist.

    Wenn die übergeordnete Ansicht nicht größer als die untergeordneten ist, macht das Erweiterungssuffix ebenfalls keinen Unterschied.

Beispiel

Schauen wir uns das folgende Beispiel an, um den Unterschied zwischen allen acht Layoutoptionen zu sehen.

Die App enthält ein Dunkelgrau StackLayoutmit acht verschachtelten weißen Schaltflächen, von denen jede mit ihrer vertikalen Layoutoption gekennzeichnet ist. Wenn Sie auf eine der Schaltflächen klicken, wird dem Stapellayout die Option für das vertikale Layout zugewiesen. Auf diese Weise können wir die Interaktion von Ansichten mit Eltern auf einfache Weise testen, beide mit unterschiedlichen Layoutoptionen.

(In den letzten Codezeilen werden zusätzliche gelbe Kästchen hinzugefügt. Wir werden gleich darauf zurückkommen.)

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

Die folgenden Screenshots zeigen das Ergebnis, wenn Sie auf eine der acht Schaltflächen klicken. Wir machen folgende Beobachtungen:

  • Solange das übergeordnete stackLayoutElement eng ist (nicht Filldie Seite), wird jeweils die vertikale Layoutoption verwendetButton Element vernachlässigbar.
  • Die vertikale Layoutoption ist nur wichtig, wenn die stackLayoutgrößer ist (z. B. durch FillAusrichtung) und die einzelnen Schaltflächen das ExpandSuffix haben.
  • Zusätzlicher Platz wird offensichtlich auf alle Schaltflächen mit ExpandSuffix verteilt. Um dies deutlicher zu sehen, haben wir zwischen jeweils zwei benachbarten Schaltflächen gelbe horizontale Linien eingefügt.
  • Schaltflächen mit mehr Platz als der gewünschten Höhe "füllen" sie nicht unbedingt aus. In diesem Fall wird das tatsächliche Verhalten durch ihre Ausrichtung gesteuert. ZB sind sie entweder oben, in der Mitte oder auf der Schaltfläche ihres Bereichs ausgerichtet oder füllen ihn vollständig aus.
  • Alle Schaltflächen erstrecken sich über die gesamte Breite des Layouts, da wir nur die ändern VerticalOptions.

Screenshots

Hier finden Sie die entsprechenden hochauflösenden Screenshots.

Falko
quelle
6
Bild sieht aus wie Midfing, lol. nur ein Scherz, es war wirklich hilfreich
Joy Rex
1
@JoyRex: Nun, vielleicht ist diese Version etwas weniger verwirrend. ;)
Falko
2
Ich habe mit der obigen Ausgabe verwechselt. start & startAndExpand sind beide die gleiche Ausgabe. Was ist der Unterschied zwischen diesen? Können Sie eine Erklärung geben, wenn möglich?
Ranjith Kumar
1
FillAndExpandist was Sie wollen, 99% der Zeit
Stephane Delcroix
1
@ RanjithKumar Sie sind die gleichen. Wenn StackLayout in einem anderen übergeordneten Element verschachtelt war, konnte FillAndExpand einen Unterschied machen - es wurde innerhalb des übergeordneten Elements erweitert .
Miha Markic
16

In der aktuellen Version von Xamarin.Forms gibt es einen kleinen Fehler. Vielleicht war es schon eine Weile dort.

CenterAndExpand Im Allgemeinen wird es nicht erweitert, und es kann verwirrend sein, es zu umgehen.

Wenn Sie beispielsweise einen StackLayoutSatz für haben CenterAndExpand, fügen Sie ein Etikett ein, das ebenfalls auf gesetzt ist. CenterAndExpandSie würden ein Etikett erwarten, das die volle Breite des hat StackLayout. Nee. Es wird nicht erweitert. Sie müssen auf StackLayout" FillAndExpand" setzen, damit das verschachtelte Label-Objekt auf die volle Breite des Objekts erweitert wird StackLayout, und dann das Label anweisen, den Text und nicht selbst als Objekt mit zu zentrieren HorizontalTextAlignment="Center". Nach meiner Erfahrung müssen sowohl das Elternteil als auch das verschachtelte Kind eingestellt sein, FillAndExpandwenn Sie wirklich sicherstellen möchten, dass es sich entsprechend erweitert.

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />
Clint StLaurent
quelle
3
"... Sie würden ein Etikett erwarten, das die volle Breite des StackLayout hat." Diese Annahme ist falsch. Expandwird nur für Kinder von StackLayout verwendet. Wenn Ihr StackLayout die Wurzel ist oder nicht in einem anderen StackLayout, Expandhat dies keine Auswirkungen. Stattdessen würde jede andere Option als Füllen als "Wrap-Inhalt" für die Größenbestimmung fungieren, was Sie sehen.
Therealjohn
Darüber hinaus funktioniert die Erweiterung nur für LayoutOptions, die dieselbe Ausrichtung wie das StackLayout haben. In diesem Fall ist das Layout "Vertikal", aber die fraglichen Optionen sind Horizontal (Gegensätze).
Therealjohn
Der Begriff "AndExpand" ist nicht eindeutig. Es könnte interpretiert werden als "so weit wie möglich erweitern" oder "nur so viel wie nötig erweitern". Ich denke, Microsoft sollte die Begriffe in etwas weniger verwirrendes ändern, wie "CenterAndExpandToParent" oder "CenterAndExpandAsNeeded"
technoman23
1

Falko gab eine gute Erklärung, aber ich wollte das mit einem anderen Bild ergänzen und wie diese Tags in xaml funktionieren, was ich die meiste Zeit bevorzuge. Ich habe ein einfaches Projekt zum Testen der Anzeigeergebnisse erstellt. Hier ist das Xaml für die Hauptseite:

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

Wie Sie sehen können, handelt es sich um ein sehr einfaches StackLayout mit einem Etikett im Inneren. Für jedes Bild unten habe ich das StackLayout gleich gehalten. Ich habe nur die horizontalen und vertikalen Optionen für den Eintrag geändert und den Text so geändert, dass die ausgewählten Optionen angezeigt werden, sodass Sie sehen können, wie sich der Eintrag bewegt und seine Größe ändert.

Start vs StartAndExpand Hier ist der Code für Start:

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

Und der für StartAndExpand verwendete Code:

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

Wie Sie sehen, gibt es optisch keinen Unterschied, außer dass in der Option StartAndExpand mehr Text verwendet wird. Dies wurde auf meinem physischen Samsung A30-Gerät getestet. Diese werden auf verschiedenen Geräten möglicherweise unterschiedlich angezeigt, aber ich denke, alle Bilder hier zeigen zusammen, dass es in Xamarin einige Fehler gibt. Im Übrigen werde ich nur die Screenshots zeigen, ich denke sie sind selbsterklärend.

End vs EndAndExpand

Center vs CenterAndExpand

Fill vs FillAndExpand

Ich empfehle außerdem, in der Microsoft-Dokumentation nach weiteren Details zu suchen . Bemerkenswert ist, dass "Erweiterung nur von einem StackLayout verwendet wird".

technoman23
quelle
Schöne Visualisierung. Aber ich verstehe nicht, warum dies Fehler in Xamarin zeigen sollte. Was verwirrend sein kann, ist, dass die Beschriftungen mehr Platz einnehmen können als ihr weißer Hintergrund (die grauen Bereiche in meinem Beispiel). Ein "Vert Center" -Label wird also in dem Bereich zentriert, den es einnimmt - nicht auf der gesamten Seite. Anscheinend ist dieses Thema nach fast sechs Jahren immer noch so verwirrend wie damals.
Falko