¿Cuál es la diferencia entre las opciones de diseño de Xamarin.Form, especialmente las de relleno y expansión?

170

En Xamarin.Forms cada uno Viewtiene las dos propiedades HorizontalOptionsy VerticalOptions. Ambos son de tipo LayoutOptionsy pueden tener uno de los siguientes valores:

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

Aparentemente, controla la alineación de la vista en la vista principal. Pero, ¿cómo es exactamente el comportamiento de cada opción individual? ¿Y cuál es la diferencia entre Filly el sufijo Expand?

Falko
fuente

Respuestas:

335

Respuesta corta

Start, Center, EndY Filldefinir la vista de alineación dentro de su espacio .

Expanddefine si ocupa más espacio si está disponible.

Teoría

La estructura LayoutOptionscontrola dos comportamientos distintos:

  1. Alineación: ¿Cómo se alinea la vista dentro de la vista principal?

    • Start: Para la alineación vertical, la vista se mueve hacia arriba. Para la alineación horizontal, este suele ser el lado izquierdo. (Pero tenga en cuenta que en dispositivos con configuración de idioma de derecha a izquierda esto es al revés, es decir, alineado a la derecha).
    • Center: La vista está centrada.
    • End: Por lo general, la vista está alineada a la derecha o abajo. (En los idiomas de derecha a izquierda, por supuesto, alineados a la izquierda).
    • Fill: Esta alineación es ligeramente diferente. La vista se extenderá a todo el tamaño de la vista principal.

    Si el padre, sin embargo, no es más grande que sus hijos, no notará ninguna diferencia entre esas alineaciones. La alineación solo es importante para las vistas principales con espacio adicional disponible.

  2. Expansión: ¿El elemento ocupará más espacio si está disponible?

    • Sufijo Expand: si la vista principal es mayor que el tamaño combinado de todos sus elementos secundarios, es decir, hay espacio adicional disponible, entonces el espacio se distribuye entre las vistas secundarias con ese sufijo. Esos niños "ocuparán" su espacio, pero no necesariamente lo "llenarán". Echaremos un vistazo a este comportamiento en el siguiente ejemplo.
    • Sin sufijo: los niños sin Expandsufijo no obtendrán espacio adicional, incluso si hay más espacio disponible.

    Nuevamente, si la vista principal no es más grande que sus elementos secundarios, el sufijo de expansión tampoco hace ninguna diferencia.

Ejemplo

Echemos un vistazo al siguiente ejemplo para ver la diferencia entre las ocho opciones de diseño.

La aplicación contiene un gris oscuro StackLayoutcon ocho botones blancos anidados, cada uno de los cuales está etiquetado con su opción de diseño vertical. Al hacer clic en uno de los botones, asigna su opción de diseño vertical al diseño de la pila. De esta forma, podemos probar fácilmente la interacción de las vistas con los padres, ambas con diferentes opciones de diseño.

(Las últimas líneas de código agregan cuadros amarillos adicionales. Volveremos a esto en 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,
        });
    }
}

Las siguientes capturas de pantalla muestran el resultado al hacer clic en cada uno de los ocho botones. Nosotros hacemos las siguientes observaciones:

  • Mientras el padre stackLayoutesté ajustado (no Fillla página), la opción de diseño vertical de cada uno Buttones insignificante.
  • La opción de diseño vertical solo es importante si stackLayoutes más grande (por ejemplo, mediante Fillalineación) y los botones individuales tienen el Expandsufijo.
  • El espacio adicional se distribuye eventualmente entre todos los botones con Expandsufijo. Para ver esto más claramente, agregamos líneas horizontales amarillas entre cada dos botones vecinos.
  • Los botones con más espacio que la altura solicitada no necesariamente lo "llenan". En este caso, el comportamiento real está controlado por su alineación. Por ejemplo, están alineados en la parte superior, central o botón de su espacio o lo llenan por completo.
  • Todos los botones abarcan todo el ancho del diseño, ya que solo modificamos el VerticalOptions.

Capturas de pantalla

Aquí encontrará las capturas de pantalla de alta resolución correspondientes.

Falko
fuente
66
la imagen se ve como [[midfing]], lol. es broma, fue realmente útil
Joy Rex
1
@JoyRex: Bueno, tal vez esta versión sea ​​un poco menos confusa. ;)
Falko
2
Me he confundido con la salida anterior. start & startAndExpand ambos son la misma salida. ¿Cuál es la diferencia entre estos? ¿Puede dar una explicación si es posible ..
Ranjith Kumar
1
FillAndExpandes lo que quieres, el 99% del tiempo
Stephane Delcroix
1
@RanjithKumar Son lo mismo. Si StackLayout estaba anidado en otro padre, entonces su FillAndExpand podría marcar la diferencia: se expandiría dentro de su padre.
Miha Markic
16

Hay un pequeño error en la versión actual de Xamarin.Forms; Tal vez ha estado allí un tiempo.

CenterAndExpand generalmente no se expande, y trabajar alrededor puede ser confuso.

Por ejemplo, si tiene un StackLayoutconjunto en CenterAndExpand, entonces coloca una etiqueta dentro de ese conjunto y CenterAndExpandtambién esperaría una etiqueta que sea de ancho completo StackLayout. No No se expandirá Debe establecer el StackLayout" FillAndExpand" para que el objeto Label anidado se expanda al ancho completo del StackLayout, luego dígale a la Label que centre el texto, no a sí mismo como un objeto, con HorizontalTextAlignment="Center". En mi experiencia, necesitas configurar tanto el padre como el hijo anidado FillAndExpandsi realmente quieres asegurarte de que se expanda para adaptarse.

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />
Clint StLaurent
fuente
3
"... esperaría una etiqueta que tenga el ancho completo de StackLayout". Esta suposición es incorrecta. Expandsolo se usa para niños de StackLayout. Por lo tanto, si su StackLayout es la raíz, o no en otro StackLayout, Expandno tiene ningún efecto. En cambio, cualquier opción que no sea Relleno actuaría como un "contenido de ajuste" para el dimensionamiento, que es lo que ve.
therealjohn
Además, la expansión solo funciona para LayoutOptions que tienen la misma orientación que StackLayout. En este caso, el diseño es "Vertical", pero las opciones en cuestión son Horizontales (opuestos).
therealjohn
El término "AndExpand" es ambiguo. Se podría interpretar como "expandir tanto como sea posible" o "expandir solo tanto como sea necesario". Creo que Microsoft debería modificar los términos a algo menos confusa, como "CenterAndExpandToParent" o "CenterAndExpandAsNeeded"
technoman23
1

Falko dio una buena explicación, pero quería agregar a eso con otro visual y cómo funcionan estas etiquetas en xaml, que es lo que prefiero usar la mayor parte del tiempo. Hice un proyecto simple para probar los resultados de la pantalla. Aquí está el Xaml para la página principal:

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

Como puede ver, es un StackLayout muy simple con una etiqueta dentro. Para cada imagen a continuación, mantuve el StackLayout igual, solo cambié las opciones horizontales y verticales para la Entrada y cambié el texto para mostrar las opciones seleccionadas, para que pueda ver cómo se mueve y cambia el tamaño de la Entrada.

Start vs StartAndExpand Aquí está el código utilizado para Inicio:

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

Y el código utilizado para StartAndExpand:

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

Como puede ver, no hay diferencia visual, aparte de que se usa más texto en la opción StartAndExpand. Esto fue probado en mi dispositivo físico Samsung A30. Estos pueden mostrarse de manera diferente en diferentes dispositivos, pero creo que todas las imágenes aquí muestran colectivamente que hay algunos errores en Xamarin. Por lo demás, solo mostraré las capturas de pantalla, creo que se explican por sí mismas.

End vs EndAndExpand

Center vs CenterAndExpand

Fill vs FillAndExpand

También recomiendo echar un vistazo a la documentación de Microsoft para obtener algunos detalles adicionales. Cabe destacar que "La expansión solo la usa un StackLayout".

technoman23
fuente
Buena visualización. Pero no veo por qué esto debería mostrar errores en Xamarin. Lo que puede ser confuso es que las etiquetas pueden ocupar más espacio que su fondo blanco (las regiones grises en mi ejemplo). Por lo tanto, la etiqueta "Vert Center" se centra en el espacio que ocupa, no en toda la página. Aparentemente, después de casi seis años, este tema sigue siendo tan confuso como antes.
Falko