El Xamarin.Forms FlexLayout

Usar FlexLayout para apilar o ajustar una colección de vistas secundarias.

El Xamarin.FormsFlexLayout es nuevo en Xamarin.Forms versión 3.0. Se basa en el módulo de diseño de caja flexible de CSS, conocido normalmente como diseño flexible o flexible-caja, lo que se denomina porque incluye muchas opciones flexibles para organizar los elementos secundarios dentro del diseño.

FlexLayout es similar al Xamarin.FormsStackLayout en que puede organizar sus elementos secundarios horizontal y verticalmente en una pila. Sin embargo, el FlexLayout también es capaz de encapsular sus elementos secundarios si hay demasiados para caber en una sola fila o columna, y también tiene muchas opciones para orientación, alineación y adaptación a varios tamaños de pantalla.

FlexLayout deriva de Layout<View> y hereda una propiedad Children de tipo IList<View>.

FlexLayout define seis propiedades enlazables públicas y cinco propiedades enlazables adjuntas que afectan al tamaño, la orientación y la alineación de sus elementos secundarios. (Si no está familiarizado con las propiedades enlazables adjuntas, consulte el artículo Propiedades adjuntas). Estas propiedades se describen en detalle en las secciones siguientes sobre Las propiedades enlazables en detalle y Las propiedades enlazables adjuntas en detalle. Sin embargo, este artículo comienza con una sección sobre algunos escenarios de uso comunes de FlexLayout que describe muchas de estas propiedades de forma más informal. Al final del artículo, verá cómo combinar FlexLayout con hojas de estilos CSS.

Escenarios de uso comunes

El programa de ejemplo contiene varias páginas que muestran algunos usos comunes de FlexLayout y le permiten experimentar con sus propiedades.

Uso de FlexLayout para una pila sencilla

En la página Pila simple se muestra cómo FlexLayout puede sustituir un StackLayout marcado pero con un marcado más sencillo. Todo lo que hay en este ejemplo se define en la página XAML. El FlexLayout contiene cuatro elementos secundarios:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.SimpleStackPage"
             Title="Simple Stack">

    <FlexLayout Direction="Column"
                AlignItems="Center"
                JustifyContent="SpaceEvenly">

        <Label Text="FlexLayout in Action"
               FontSize="Large" />

        <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />

        <Button Text="Do-Nothing Button" />

        <Label Text="Another Label" />
    </FlexLayout>
</ContentPage>

Esta es la página que se ejecuta en iOS, Android y la Plataforma universal de Windows:

Página Pila simple

Tres propiedades de FlexLayout se muestran en el archivo SimpleStackPage.xaml:

  • La propiedad Direction se establece en un valor de la enumeración FlexDirection. El valor predeterminado es Row. Establecer la propiedad en Column hace que los elementos secundarios del FlexLayout se organicen en una sola columna de elementos.

    Cuando los elementos de un FlexLayout se organizan en una columna, se dice que el FlexLayout tiene un eje principal vertical y un eje cruzado horizontal.

  • La propiedad AlignItems es de tipo FlexAlignItems y especifica cómo se alinean los elementos en el eje cruzado. La opción Center hace que cada elemento se centre horizontalmente.

    Si estuviera usando un StackLayout en lugar de un FlexLayout para esta tarea, centraría todos los elementos asignando la propiedad HorizontalOptions de cada elemento a Center. La propiedad HorizontalOptions no funciona para los elementos secundarios de un FlexLayout, pero la única propiedad AlignItems logra el mismo objetivo. Si es necesario, puede usar la propiedad enlazable adjunta AlignSelf para invalidar la propiedad AlignItems para elementos individuales:

    <Label Text="FlexLayout in Action"
           FontSize="Large"
           FlexLayout.AlignSelf="Start" />
    

    Con ese cambio, este Label se coloca en el borde izquierdo del FlexLayout cuando el orden de lectura es de izquierda a derecha.

  • La propiedad JustifyContent es de tipo FlexJustifyy especifica cómo se organizan los elementos en el eje principal. La opción SpaceEvenly asigna todo el espacio vertical restante de forma equitativa entre todos los elementos, y por encima del primer elemento, y por debajo del último elemento.

    Si estuviera usando, StackLayouttendría que asignar la VerticalOptions propiedad de cada elemento para CenterAndExpand lograr un efecto similar. Pero la opción CenterAndExpand asignaría el doble de espacio entre cada elemento que antes del primer elemento y después del último elemento. Puede imitar la CenterAndExpandopción de VerticalOptions estableciendo la propiedad JustifyContent de FlexLayout en SpaceAround.

Estas propiedades FlexLayout se describen con más detalle en la sección Las propiedades enlazables en detalle a continuación.

Uso de FlexLayout para ajustar elementos

La página Ajuste de fotos de la muestra muestra cómo FlexLayout puede ajustar sus elementos secundarios a filas o columnas adicionales. El archivo XAML crea una instancia del FlexLayout y le asigna dos propiedades:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FlexLayoutDemos.PhotoWrappingPage"
             Title="Photo Wrapping">
    <Grid>
        <ScrollView>
            <FlexLayout x:Name="flexLayout"
                        Wrap="Wrap"
                        JustifyContent="SpaceAround" />
        </ScrollView>

        <ActivityIndicator x:Name="activityIndicator"
                           IsRunning="True"
                           VerticalOptions="Center" />
    </Grid>
</ContentPage>

No se establece la propiedad Direction de este FlexLayout, por lo que tiene el valor predeterminado de Row, lo que significa que los elementos secundarios se organizan en filas y el eje principal es horizontal.

La propiedad Wrap es de un tipo de enumeración FlexWrap. Si hay demasiados elementos que caben en una fila, esta configuración de propiedad hace que los elementos se ajusten a la siguiente fila.

Observe que el FlexLayout es un elemento secundario de un ScrollView. Si hay demasiadas filas que caben en la página, el ScrollView tiene una propiedad Orientation predeterminada de Vertical y permite el desplazamiento vertical.

La propiedad JustifyContent asigna espacio restante en el eje principal (el eje horizontal) para que cada elemento esté rodeado por la misma cantidad de espacio en blanco.

El archivo de código subyacente accede a una colección de fotos de ejemplo y los agrega a la colección Children de la FlexLayout:

public partial class PhotoWrappingPage : ContentPage
{
    // Class for deserializing JSON list of sample bitmaps
    [DataContract]
    class ImageList
    {
        [DataMember(Name = "photos")]
        public List<string> Photos = null;
    }

    public PhotoWrappingPage ()
    {
        InitializeComponent ();

        LoadBitmapCollection();
    }

    async void LoadBitmapCollection()
    {
        using (WebClient webClient = new WebClient())
        {
            try
            {
                // Download the list of stock photos
                Uri uri = new Uri("https://raw.githubusercontent.com/xamarin/docs-archive/master/Images/stock/small/stock.json");
                byte[] data = await webClient.DownloadDataTaskAsync(uri);

                // Convert to a Stream object
                using (Stream stream = new MemoryStream(data))
                {
                    // Deserialize the JSON into an ImageList object
                    var jsonSerializer = new DataContractJsonSerializer(typeof(ImageList));
                    ImageList imageList = (ImageList)jsonSerializer.ReadObject(stream);

                    // Create an Image object for each bitmap
                    foreach (string filepath in imageList.Photos)
                    {
                        Image image = new Image
                        {
                            Source = ImageSource.FromUri(new Uri(filepath))
                        };
                        flexLayout.Children.Add(image);
                    }
                }
            }
            catch
            {
                flexLayout.Children.Add(new Label
                {
                    Text = "Cannot access list of bitmap files"
                });
            }
        }

        activityIndicator.IsRunning = false;
        activityIndicator.IsVisible = false;
    }
}

Este es el programa en ejecución, desplazado progresivamente de arriba a abajo:

Página Ajuste de fotos

Diseño de página con FlexLayout

Hay un diseño estándar en el diseño web llamado el santo grial porque es un formato de diseño muy deseable, pero a menudo difícil de realizar perfección. El diseño consta de un encabezado en la parte superior de la página y un pie de página en la parte inferior; ambos se extienden al ancho completo de la página. Ocupar el centro de la página es el contenido principal, pero a menudo con un menú en columnas a la izquierda del contenido y la información complementaria (a veces denominada de reserva) a la derecha. Sección 5.4.1 de la especificación de diseño de caja flexible CSS describe cómo se puede realizar el diseño del holy grial con un cuadro flexible.

En la página Diseño del Holy Grial de la muestra muestra una implementación sencilla de este diseño con un FlexLayout anidado en otro. Dado que esta página está diseñada para un teléfono en modo vertical, las áreas situadas a la izquierda y a la derecha del área de contenido solo tienen un ancho de 50 píxeles:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FlexLayoutDemos.HolyGrailLayoutPage"
             Title="Holy Grail Layout">

    <FlexLayout Direction="Column">

        <!-- Header -->
        <Label Text="HEADER"
               FontSize="Large"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center" />

        <!-- Body -->
        <FlexLayout FlexLayout.Grow="1">

            <!-- Content -->
            <Label Text="CONTENT"
                   FontSize="Large"
                   BackgroundColor="Gray"
                   HorizontalTextAlignment="Center"
                   VerticalTextAlignment="Center"
                   FlexLayout.Grow="1" />

            <!-- Navigation items-->
            <BoxView FlexLayout.Basis="50"
                     FlexLayout.Order="-1"
                     Color="Blue" />

            <!-- Aside items -->
            <BoxView FlexLayout.Basis="50"
                     Color="Green" />

        </FlexLayout>

        <!-- Footer -->
        <Label Text="FOOTER"
               FontSize="Large"
               BackgroundColor="Pink"
               HorizontalTextAlignment="Center" />
    </FlexLayout>
</ContentPage>

Aquí se está ejecutando:

Página Diseño del Santo Grial

Las áreas de navegación y de reserva se representan con un elemento BoxView a la izquierda y a la derecha.

El primer FlexLayout del archivo XAML tiene un eje principal vertical y contiene tres elementos secundarios organizados en una columna. Estos son el encabezado, el cuerpo de la página y el pie de página. El FlexLayout anidado tiene un eje principal horizontal con tres elementos secundarios organizados en una fila.

En este programa se muestran tres propiedades enlazables adjuntas:

  • La propiedad enlazable adjunta Order se establece en el primer BoxView. Esta propiedad es un entero con un valor predeterminado de 0. Puede usar esta propiedad para cambiar el orden de diseño. Por lo general, los desarrolladores prefieren que el contenido de la página aparezca en el marcado antes de los elementos de navegación y los elementos de reserva. Establecer la propiedad Order en el primer BoxView en un valor menor que sus otros elementos relacionados hace que aparezca como el primer elemento de la fila. Del mismo modo, puede asegurarse de que un elemento aparece por última vez estableciendo la propiedad Order en un valor mayor que sus elementos del mismo nivel.

  • La propiedad enlazable adjunta Basis se establece en los dos elementos BoxView para darles un ancho de 50 píxeles. Esta propiedad es de tipo FlexBasis, una estructura que define una propiedad estática de tipo FlexBasis denominada Auto, que es el valor predeterminado. Puede usar Basis para especificar un tamaño de píxel o un porcentaje que indique cuánto espacio ocupa el elemento en el eje principal. Se denomina base porque especifica un tamaño de elemento que es la base de todo el diseño posterior.

  • La propiedad Grow se establece en el Layout anidado y en el elemento secundario Label que representa el contenido. Esta propiedad es de tipo float y tiene un valor predeterminado de 0. Cuando se establece en un valor positivo, todo el espacio restante a lo largo del eje principal se asigna a ese elemento y a los elementos del mismo nivel con valores positivos de Grow. El espacio se asigna proporcionalmente a los valores, algo parecido a la especificación de estrella en un Grid.

    La primera Grow propiedad adjunta se establece en el FlexLayoutanidado , lo que indica que este FlexLayout es ocupar todo el espacio vertical sin usar dentro del FlexLayoutexterno. La segunda Grow propiedad adjunta se establece en el Label que representa el contenido, lo que indica que este contenido va a ocupar todo el espacio horizontal sin usar dentro del FlexLayoutinterno.

    También hay una propiedad enlazable adjunta similar Shrink que se puede usar cuando el tamaño de los elementos secundarios supera el tamaño del FlexLayout, pero no se desea ajustar.

Elementos de catálogo con FlexLayout

La página Elementos de catálogo de la muestra es similar a ejemplo 1 de la sección 1.1 de la especificación CSS Flex Layout Box excepto que muestra una serie de imágenes y descripciones desplazables horizontalmente de tres monos:

Página Elementos de catálogo

Cada uno de los tres monos es un FlexLayout contenido en un Frame que se da un alto y ancho explícitos, y que también es un elemento secundario de un FlexLayout mayor. En este archivo XAML, la mayoría de las propiedades de los elementos secundarios de FlexLayout se especifican en estilos, pero uno de los cuales es un estilo implícito:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.CatalogItemsPage"
             Title="Catalog Items">
    <ContentPage.Resources>
        <Style TargetType="Frame">
            <Setter Property="BackgroundColor" Value="LightYellow" />
            <Setter Property="BorderColor" Value="Blue" />
            <Setter Property="Margin" Value="10" />
            <Setter Property="CornerRadius" Value="15" />
        </Style>

        <Style TargetType="Label">
            <Setter Property="Margin" Value="0, 4" />
        </Style>

        <Style x:Key="headerLabel" TargetType="Label">
            <Setter Property="Margin" Value="0, 8" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="TextColor" Value="Blue" />
        </Style>

        <Style TargetType="Image">
            <Setter Property="FlexLayout.Order" Value="-1" />
            <Setter Property="FlexLayout.AlignSelf" Value="Center" />
        </Style>

        <Style TargetType="Button">
            <Setter Property="Text" Value="LEARN MORE" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="TextColor" Value="White" />
            <Setter Property="BackgroundColor" Value="Green" />
            <Setter Property="BorderRadius" Value="20" />
        </Style>
    </ContentPage.Resources>

    <ScrollView Orientation="Both">
        <FlexLayout>
            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Seated Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
                    <Label Text="  &#x2022; Doesn't make a lot of noise" />
                    <Label Text="  &#x2022; Often smiles mysteriously" />
                    <Label Text="  &#x2022; Sleeps sitting up" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}"
                           WidthRequest="180"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Banana Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="Watch this monkey eat a giant banana." />
                    <Label Text="  &#x2022; More fun than a barrel of monkeys" />
                    <Label Text="  &#x2022; Banana not included" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}"
                           WidthRequest="240"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Face-Palm Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
                    <Label Text="  &#x2022; Cynical but not unfriendly" />
                    <Label Text="  &#x2022; Seven varieties of grimaces" />
                    <Label Text="  &#x2022; Doesn't laugh at your jokes" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}"
                           WidthRequest="180"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>
        </FlexLayout>
    </ScrollView>
</ContentPage>

El estilo implícito del Image incluye la configuración de dos propiedades enlazables adjuntas de Flexlayout:

<Style TargetType="Image">
    <Setter Property="FlexLayout.Order" Value="-1" />
    <Setter Property="FlexLayout.AlignSelf" Value="Center" />
</Style>

El valor Order de –1 hace que el elemento Image se muestre primero en cada una de las vistas FlexLayout anidadas independientemente de su posición dentro de la colección secundaria. La propiedad AlignSelf de Center hace que el Image se centre dentro del FlexLayout. Esto invalida el valor de la propiedad AlignItems, que tiene un valor predeterminado de Stretch, lo que significa que los elementos secundarios Label y Button se extienden al ancho completo del FlexLayout.

Dentro de cada una de las tres vistas de FlexLayout, un en blanco Label precede al Button, pero tiene un valor Grow de 1. Esto significa que todo el espacio vertical adicional se asigna a este Labelen blanco, que inserta eficazmente el Button en la parte inferior.

Propiedades enlazables en detalle

Ahora que ha visto algunas aplicaciones comunes de FlexLayout, las propiedades de FlexLayout se pueden explorar con más detalle. FlexLayout define seis propiedades enlazables que se establecen en la propia FlexLayout, ya sea en código o XAML, para controlar la orientación y la alineación. (Una de estas propiedades, Position, no se trata en este artículo).

Puede experimentar con las cinco propiedades enlazables restantes mediante la página Experimento de la muestra. Esta página permite agregar o quitar elementos secundarios de un FlexLayout y establecer combinaciones de las cinco propiedades enlazables. Todos los elementos secundarios de la FlexLayout son Label vistas de varios colores y tamaños, con la propiedad Text establecida en un número correspondiente a su posición en la colección Children.

Cuando se inicia el programa, cinco vistas Picker muestran los valores predeterminados de estas cinco propiedades FlexLayout. El FlexLayout hacia la parte inferior de la pantalla contiene tres elementos secundarios:

Página Experimento: valor predeterminado

Cada una de las vistas de Label tiene un fondo gris que muestra el espacio asignado a ese Label dentro de la FlexLayout. El fondo del FlexLayout es Alice Blue. Ocupa todo el área inferior de la página, excepto un poco de margen a la izquierda y a la derecha.

La propiedad Direction

La propiedad Direction es de tipo FlexDirection, una enumeración con cuatro miembros:

  • Column
  • ColumnReverse (o "columna-inversa" en XAML)
  • Row, la opción predeterminada
  • RowReverse (o "fila inversa" en XAML)

En XAML, puedes especificar el valor de esta propiedad con los nombres de miembro de enumeración en minúsculas, mayúsculas o minúsculas mixtas, o puedes usar dos cadenas adicionales que se muestran entre paréntesis que son iguales que los indicadores CSS. (Las cadenas "columna-inversa" y "fila-inversa" se definen en la clase FlexDirectionTypeConverter usada por el analizador XAML).

Esta es la página experimento de que muestra (de izquierda a derecha), la dirección Row, la dirección Column y la dirección ColumnReverse:

Página Experimento: dirección

Observe que para las opciones de Reverse, los elementos comienzan en la parte inferior o derecha.

La propiedad Wrap

La propiedad Wrap es de tipo FlexWrap, una enumeración con tres miembros:

  • NoWrap, la opción predeterminada
  • Wrap
  • Reverse (o "encapsular inverso" en XAML)

De izquierda a derecha, estas pantallas muestran las opciones de NoWrap, Wrap y Reverse para 12 elementos secundarios:

Página Experimento: encapsular

Cuando la propiedad Wrap se establece en NoWrap y el eje principal está restringido (como en este programa) y el eje principal no es lo suficientemente ancho como para ajustarse a todos los elementos secundarios, el FlexLayout intenta hacer que los elementos sean más pequeños, como se muestra en la captura de pantalla de iOS. Puede controlar la reducción de los elementos con la propiedad enlazable adjunta Shrink.

La propiedad JustifyContent

La propiedad JustifyContent es de tipo FlexJustify, una enumeración con seis miembros:

  • Start (o "flex-start" en XAML), el valor predeterminado
  • Center
  • End (o "flex-end" en XAML)
  • SpaceBetween (o "espacio entre" en XAML)
  • SpaceAround (o "espacio alrededor" en XAML)
  • SpaceEvenly

Esta propiedad especifica cómo los elementos están espaciados en el eje principal, que es el eje horizontal de este ejemplo:

Página Experimento: justificar contenido

En las tres capturas de pantalla, la propiedad Wrap se establece en Wrap. El Start valor predeterminado se muestra en la captura de pantalla anterior de Android. La captura de pantalla de iOS aquí muestra la opción Center: todos los elementos se mueven al centro. Las otras tres opciones que comienzan por la palabra Space asignan el espacio adicional no ocupado por los elementos. SpaceBetween asigna el espacio de forma equitativa entre los elementos; SpaceAround coloca el espacio igual alrededor de cada elemento, mientras que SpaceEvenly coloca el mismo espacio entre cada elemento y antes del primer elemento y después del último elemento de la fila.

La propiedad AlignItems

La propiedad AlignItems es de tipo FlexAlignItems, una enumeración con cuatro miembros:

  • Stretch, la opción predeterminada
  • Center
  • Start (o "flex-start" en XAML)
  • End (o "flex-end" en XAML)

Esta es una de las dos propiedades (la otra es AlignContent) que indica cómo se alinean los elementos secundarios en el eje cruzado. Dentro de cada fila, los elementos secundarios se extienden (como se muestra en la captura de pantalla anterior) o se alinean en el inicio, el centro o el final de cada elemento, como se muestra en las tres capturas de pantalla siguientes:

Página Experimento: alinear elementos

En la captura de pantalla de iOS, las principales de todos los elementos secundarios están alineadas. En las capturas de pantalla de Android, los elementos se centran verticalmente en función del elemento secundario más alto. En la captura de pantalla de UWP, se alinean las parte inferior de todos los elementos.

Para cualquier elemento individual, la configuración de AlignItems se puede invalidar con la propiedad enlazable adjunta AlignSelf.

La propiedad AlignContent

La propiedad AlignContent es de tipo FlexAlignContent, una enumeración con siete miembros:

  • Stretch, la opción predeterminada
  • Center
  • Start (o "flex-start" en XAML)
  • End (o "flex-end" en XAML)
  • SpaceBetween (o "espacio entre" en XAML)
  • SpaceAround (o "espacio alrededor" en XAML)
  • SpaceEvenly

Al igual que AlignItems, la propiedad AlignContent también alinea los elementos secundarios en el eje cruzado, pero afecta a filas o columnas completas:

Página Experimento: alinear contenido

En la captura de pantalla de iOS, ambas filas están en la parte superior; en la captura de pantalla de Android que están en el centro; y en la captura de pantalla de UWP están en la parte inferior. Las filas también se pueden espaciar de varias maneras:

Página Experimento: alinear contenido 2

El AlignContent no tiene ningún efecto cuando solo hay una fila o columna.

Propiedades enlazables adjuntas con detalle

FlexLayout define cinco propiedades enlazables adjuntas. Estas propiedades se establecen en elementos secundarios del FlexLayout y pertenecen solo a ese elemento secundario en particular.

La propiedad AlignSelf

La propiedad enlazable adjunta AlignSelf es de tipo FlexAlignSelf, una enumeración con cinco miembros:

  • Auto, la opción predeterminada
  • Stretch
  • Center
  • Start (o "flex-start" en XAML)
  • End (o "flex-end" en XAML)

Para cualquier elemento secundario individual del FlexLayout, esta configuración de propiedad invalida la propiedad AlignItems establecida en el propio FlexLayout. El valor predeterminado de Auto significa usar la configuración AlignItems.

Para un elemento de Label denominado label (o ejemplo), puede establecer la propiedad AlignSelf en código de la siguiente manera:

FlexLayout.SetAlignSelf(label, FlexAlignSelf.Center);

Observe que no hay ninguna referencia al FlexLayout primario del Label. En XAML, estableces la propiedad de la siguiente manera:

<Label ... FlexLayout.AlignSelf="Center" ... />

La propiedad Order

La propiedad Order es de tipo int. El valor predeterminado es 0.

La propiedad Order permite cambiar el orden en que se organizan los elementos secundarios del FlexLayout. Normalmente, los elementos secundarios de un FlexLayout se organizan es el mismo orden en que aparecen en la colección Children. Puede invalidar este orden estableciendo la propiedad enlazable adjunta Order en un valor entero distinto de cero en uno o varios elementos secundarios. A continuación, el FlexLayout organiza sus elementos secundarios en función del valor de la propiedad Order en cada elemento secundario, pero los elementos secundarios con la misma configuración de Order se organizan en el orden en que aparecen en la colección Children.

La propiedad Basis

La propiedad enlazable adjunta Basis indica la cantidad de espacio asignado a un elemento secundario del FlexLayout en el eje principal. El tamaño especificado por la propiedad Basis es el tamaño a lo largo del eje principal del FlexLayoutprimario. Por lo tanto, Basis indica el ancho de un elemento secundario cuando los elementos secundarios se organizan en filas o el alto cuando los elementos secundarios se organizan en columnas.

La propiedad Basis es de tipo FlexBasis, una estructura. El tamaño se puede especificar en unidades independientes del dispositivo o como porcentaje del tamaño de la FlexLayout. El valor predeterminado de la propiedad Basis es la propiedad estática FlexBasis.Auto, lo que significa que se usa el ancho o alto solicitados del elemento secundario.

En el código, puede establecer la propiedad Basis para un Label denominado label en 40 unidades independientes del dispositivo como esta:

FlexLayout.SetBasis(label, new FlexBasis(40, false));

El segundo argumento para el constructor FlexBasis se denomina isRelative e indica si el tamaño es relativo (true) o absoluto (false). El argumento tiene un valor predeterminado de false, por lo que también puede usar el código siguiente:

FlexLayout.SetBasis(label, new FlexBasis(40));

Se define una conversión implícita de float a FlexBasis, por lo que puede simplificarla aún más:

FlexLayout.SetBasis(label, 40);

Puede establecer el tamaño en el 25 % del FlexLayout primario de la siguiente manera:

FlexLayout.SetBasis(label, new FlexBasis(0.25f, true));

Este valor fraccionario debe estar en el intervalo de 0 a 1.

En XAML, puedes usar un número para un tamaño en unidades independientes del dispositivo:

<Label ... FlexLayout.Basis="40" ... />

O bien, puede especificar un porcentaje en el intervalo del 0 % al 100 %:

<Label ... FlexLayout.Basis="25%" ... />

La página Experimento de base de la muestra le permite experimentar con la propiedad Basis. La página muestra una columna ajustada de cinco Label elementos con colores de fondo y primer plano alternados. Dos elementos Slider permiten especificar valores Basis para el segundo y cuarto Label:

Página Experimento base

En la captura de pantalla de iOS de la izquierda se muestran los dos elementos Label que se proporcionan alturas en unidades independientes del dispositivo. La pantalla de Android muestra que se les asignan alturas que son una fracción del alto total de la FlexLayout. Si el Basis se establece en un 100 %, el elemento secundario es el alto del FlexLayout, y se ajustará a la columna siguiente y ocupará todo el alto de esa columna, como se muestra en la captura de pantalla de UWP: Aparece como si los cinco elementos secundarios se organizan en una fila, pero realmente se organizan en cinco columnas.

La propiedad Grow

La propiedad enlazable adjunta Grow es de tipo int. El valor predeterminado es 0 y el valor debe ser mayor o igual que 0.

La propiedad Grow desempeña un rol cuando la propiedad Wrap se establece en NoWrap y la fila de elementos secundarios tiene un ancho total menor que el ancho de la FlexLayouto la columna de elementos secundarios tiene un alto más corto que el FlexLayout. La propiedad Grow indica cómo asignar el espacio restante entre los elementos secundarios.

En la página Grow Experiment, cinco Label elementos de colores alternados se organizan en una columna y dos elementos Slider permiten ajustar la propiedad Grow del segundo y cuarto Label. La captura de pantalla de iOS en el extremo izquierdo muestra las propiedades de Grow predeterminadas de 0:

Página Experimento de crecimiento

Si a un elemento secundario se le asigna un valor positivo Grow, ese elemento secundario ocupa todo el espacio restante, como se muestra en la captura de pantalla de Android. Este espacio también se puede asignar entre dos o más elementos secundarios. En la captura de pantalla de UWP, la propiedad Grow del segundo Label se establece en 0,5, mientras que la propiedad Grow del cuarto Label es 1,5, lo que da al cuarto Label tres veces la mayor parte del espacio restante como segundo Label.

La forma en que la vista secundaria usa ese espacio depende del tipo determinado de elemento secundario. Para un Label, el texto se puede colocar dentro del espacio total del Label mediante las propiedades HorizontalTextAlignment y VerticalTextAlignment.

La propiedad Shrink

La propiedad enlazable adjunta Shrink es de tipo int. El valor predeterminado es 1 y el valor debe ser mayor o igual que 0.

La propiedad Shrink desempeña un rol cuando la propiedad Wrap se establece en NoWrap y el ancho agregado de una fila de elementos secundarios es mayor que el ancho de la FlexLayouto el alto agregado de una sola columna de elementos secundarios es mayor que el alto de la FlexLayout. Normalmente, FlexLayout mostrará estos elementos secundarios limitando sus tamaños. La propiedad Shrink puede indicar qué elementos secundarios tienen prioridad al mostrarse en sus tamaños completos.

La página Shrink Experiment crea un FlexLayout con una sola fila de cinco Label elementos secundarios que requieren más espacio que el ancho del FlexLayout . La captura de pantalla de iOS de la izquierda muestra todos los elementos Label con valores predeterminados de 1:

Página Reducir de reducción

En la captura de pantalla de Android, el valor de Shrink del segundo Label se establece en 0 y que Label se muestra en su ancho completo. Además, al cuarto Label se le asigna un valor Shrink mayor que uno y se ha reducido. En la captura de pantalla de UWP se muestran ambos elementos Label que se les asigna un valor Shrink de 0 para permitir que se muestren en su tamaño completo, si es posible.

Puede establecer los valores de Grow y Shrink para dar cabida a situaciones en las que los tamaños secundarios agregados pueden ser menores que o a veces mayores que el tamaño de la FlexLayout.

Estilos CSS con FlexLayout

Puede usar la característica de estilo CSS de introducida con Xamarin.Forms 3.0 en conexión con FlexLayout. La página Elementos del catálogo CSS de muestra duplica el diseño de la página Elementos de catálogo, pero con una hoja de estilos CSS para muchos de los estilos:

Página Elementos del catálogo CSS

El archivo CatalogItemsPage.xaml original tiene cinco definiciones de Style en su sección de Resources con 15 objetos Setter. En el archivo cssCatalogItemsPage.xaml , que se ha reducido a dos definiciones de Style con solo cuatro objetos Setter. Estos estilos complementan la hoja de estilos CSS para las propiedades que la característica de estilo CSS de Xamarin.Forms actualmente no admite:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.CssCatalogItemsPage"
             Title="CSS Catalog Items">
    <ContentPage.Resources>
        <StyleSheet Source="CatalogItemsStyles.css" />

        <Style TargetType="Frame">
            <Setter Property="BorderColor" Value="Blue" />
            <Setter Property="CornerRadius" Value="15" />
        </Style>

        <Style TargetType="Button">
            <Setter Property="Text" Value="LEARN MORE" />
            <Setter Property="BorderRadius" Value="20" />
        </Style>
    </ContentPage.Resources>

    <ScrollView Orientation="Both">
        <FlexLayout>
            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Seated Monkey" StyleClass="header" />
                    <Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
                    <Label Text="  &#x2022; Doesn't make a lot of noise" />
                    <Label Text="  &#x2022; Often smiles mysteriously" />
                    <Label Text="  &#x2022; Sleeps sitting up" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Banana Monkey" StyleClass="header" />
                    <Label Text="Watch this monkey eat a giant banana." />
                    <Label Text="  &#x2022; More fun than a barrel of monkeys" />
                    <Label Text="  &#x2022; Banana not included" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Face-Palm Monkey" StyleClass="header" />
                    <Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
                    <Label Text="  &#x2022; Cynical but not unfriendly" />
                    <Label Text="  &#x2022; Seven varieties of grimaces" />
                    <Label Text="  &#x2022; Doesn't laugh at your jokes" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>
        </FlexLayout>
    </ScrollView>
</ContentPage>

Se hace referencia a la hoja de estilos CSS en la primera línea de la sección Resources:

<StyleSheet Source="CatalogItemsStyles.css" />

Observe también que dos elementos de cada uno de los tres elementos incluyen StyleClass configuración:

<Label Text="Seated Monkey" StyleClass="header" />
···
<Label StyleClass="empty" />

Estos hacen referencia a los selectores de la hoja de estilos de CatalogItemsStyles.css:

frame {
    width: 300;
    height: 480;
    background-color: lightyellow;
    margin: 10;
}

label {
    margin: 4 0;
}

label.header {
    margin: 8 0;
    font-size: large;
    color: blue;
}

label.empty {
    flex-grow: 1;
}

image {
    height: 180;
    order: -1;
    align-self: center;
}

button {
    font-size: large;
    color: white;
    background-color: green;
}

Aquí se hace referencia a varias FlexLayout propiedades enlazables adjuntas. En el selector de label.empty, verá el atributo flex-grow, que estilos un Label vacío para proporcionar espacio en blanco encima del Button. El selector de image contiene un atributo order y un atributo align-self, los cuales corresponden a FlexLayout propiedades enlazables adjuntas.

Ha visto que puede establecer propiedades directamente en el FlexLayout y puede establecer propiedades enlazables adjuntas en los elementos secundarios de un FlexLayout. O bien, puedes establecer estas propiedades indirectamente mediante estilos tradicionales basados en XAML o estilos CSS. Lo importante es saber y comprender estas propiedades. Estas propiedades son lo que hace que el FlexLayout sea verdaderamente flexible.

FlexLayout con Xamarin.University

Xamarin.Formsvídeo de diseño flexible de 3.0