web-dev-qa-db-fra.com

Quelle est la différence entre les LayoutOptions de Xamarin.Form, en particulier Fill and Expand?

En Xamarin.Forms chaque View a les deux propriétés HorizontalOptions et VerticalOptions. Les deux sont de type LayoutOptions et peuvent avoir l'une des valeurs suivantes:

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

Apparemment, il contrôle l'alignement de la vue sur la vue parent. Mais comment se comporte exactement le comportement de chaque option? Et quelle est la différence entre Fill et le suffixe Expand?

158
Falko

Réponse courte

Start, Center, End et Fill définissent l'alignement de la vue dans son espace .

Expand définit s'il occupe plus d'espace s'il est disponible.

Théorie

La structure LayoutOptions contrôle deux comportements distincts:

  1. Alignement: Comment la vue est-elle alignée dans la vue parent?

    • Start: Pour l'alignement vertical, la vue est déplacée vers le haut. Pour l'alignement horizontal, il s'agit généralement du côté gauche. (Notez cependant que sur les appareils avec un réglage de langue de droite à gauche, c’est l’inverse, c’est-à-dire aligné à droite.)
    • Center: La vue est centrée.
    • End: La vue est généralement alignée en bas ou à droite. (Sur les langues de droite à gauche, bien sûr, aligné à gauche.)
    • Fill: Cet alignement est légèrement différent. La vue s'étendra sur toute la taille de la vue parent.

    Cependant, si le parent n’est pas plus grand que ses enfants, vous ne remarquerez aucune différence entre ces alignements. L'alignement ne concerne que les vues parent avec de l'espace supplémentaire disponible.

  2. Expansion: L'élément occupera-t-il plus d'espace s'il est disponible?

    • Suffixe Expand: Si la vue parent est plus grande que la taille combinée de tous ses enfants, c'est-à-dire qu'un espace supplémentaire est disponible, l'espace est alors proportionné parmi les vues d'enfants portant ce suffixe. Ces enfants "occuperont" leur espace, mais ne le "rempliront" pas nécessairement. Nous verrons ce comportement dans l'exemple ci-dessous.
    • Pas de suffixe: les enfants sans le suffixe Expand n'obtiendront pas d'espace supplémentaire, même si davantage d'espace est disponible.

    De nouveau, si la vue parent n’est pas plus grande que ses enfants, le suffixe d’extension ne fait aucune différence.

Exemple

Examinons l'exemple suivant pour voir la différence entre les huit options de présentation.

L'application contient un StackLayout gris foncé avec huit boutons blancs imbriqués, chacun d'eux étant étiqueté avec son option de disposition verticale. En cliquant sur l'un des boutons, il assigne son option de disposition verticale à la disposition de la pile. De cette façon, nous pouvons facilement tester l’interaction des vues avec les parents, les deux avec une option de disposition différente.

(Les dernières lignes de code ajoutent des cases jaunes supplémentaires. Nous y reviendrons dans un instant.)

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

Les captures d'écran suivantes montrent le résultat en cliquant sur chacun des huit boutons. Nous faisons les observations suivantes:

  • Tant que le parent stackLayout est serré (et non Fill la page), l'option de disposition verticale de chaque Button est négligeable.
  • L'option de disposition verticale n'a d'importance que si le stackLayout est plus grand (par exemple, via Fill alignement) et si les boutons individuels portent le suffixe Expand.
  • L'espace supplémentaire est éventuellement proportionné parmi tous les boutons avec le suffixe Expand. Pour voir cela plus clairement, nous avons ajouté des lignes horizontales jaunes entre chaque deux boutons voisins.
  • Les boutons avec plus d'espace que la hauteur demandée ne le "remplissent" pas nécessairement. Dans ce cas, le comportement réel est contrôlé par leur alignement. Par exemple. ils sont soit alignés sur le haut, le centre ou le bouton de leur espace, soit le remplissent complètement.
  • Tous les boutons couvrent toute la largeur de la présentation, car nous ne modifions que le VerticalOptions.

Screenshots

Vous trouverez ici les captures d'écran haute résolution correspondantes.

319
Falko

Il y a un bogue dans la version actuelle de Xamarin.Forms; peut-être y a-t-il eu un moment.

CenterAndExpand généralement ne se développe pas, et travailler à ce sujet peut être déroutant.

Par exemple, si vous avez défini StackLayout sur CenterAndExpand, vous placez une étiquette à l'intérieur de celle-ci également définie sur CenterAndExpand vous vous attendez à une étiquette pleine largeur de StackLayout . Nan. Ça ne va pas s'étendre. Vous devez définir la StackLayout sur "FillAndExpand" pour que l’objet Label imbriqué s’agrandisse sur toute la largeur du StackLayout, puis indiquez à l’étiquette de centrer le texte et non lui-même. un objet, avec HorizontalTextAlignment="Center". D'après mon expérience, il faut que le parent et l'enfant imbriqué soient réglés sur FillAndExpand si vous voulez vraiment vous assurer qu'il s'agrandit.

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