Escolher um Xamarin.Forms Layout

Baixar exemplo Baixar o exemplo

Xamarin.Forms as classes de layout permitem organizar e agrupar controles de interface do usuário em seu aplicativo. Escolher uma classe de layout requer conhecimento de como o layout posiciona seus elementos filho e como o layout dimensiona seus elementos filho. Além disso, pode ser necessário aninhar layouts para criar o layout desejado.

A imagem a seguir mostra layouts típicos que podem ser obtidos com as classes de layout mainXamarin.Forms:

As classes de layout main em Xamarin.Forms

StackLayout

Um StackLayout organiza elementos em uma pilha unidimensional, horizontal ou verticalmente. A Orientation propriedade especifica a direção dos elementos e a orientação padrão é Vertical. StackLayout normalmente é usado para organizar uma subseção da interface do usuário em uma página.

O XAML a seguir mostra como criar um vertical StackLayout contendo três Label objetos:

<StackLayout Margin="20,35,20,25">
    <Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
    <Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
    <Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>

Em um StackLayout, se o tamanho de um elemento não estiver definido explicitamente, ele se expandirá para preencher a largura ou a altura disponíveis se a Orientation propriedade estiver definida como Horizontal.

Um StackLayout geralmente é usado como um layout pai, que contém outros layouts filho. No entanto, um StackLayout não deve ser usado para reproduzir um Grid layout usando uma combinação de StackLayout objetos. O código a seguir mostra um exemplo dessa prática incorreta:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name:" />
            <Entry Placeholder="Enter your name" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Age:" />
            <Entry Placeholder="Enter your age" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Occupation:" />
            <Entry Placeholder="Enter your occupation" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Address:" />
            <Entry Placeholder="Enter your address" />
        </StackLayout>
    </StackLayout>
</ContentPage>

Isso é um desperdício porque cálculos de layout desnecessário são executados. Em vez disso, o layout desejado pode ser melhor obtido usando um Grid.

Dica

Ao usar um StackLayout, verifique se apenas um elemento filho está definido como LayoutOptions.Expands. Essa propriedade garante que o filho especificado ocupe o maior espaço que o StackLayout pode dar a ele e é um desperdício executar esses cálculos mais de uma vez.

Para obter mais informações, consulte Xamarin.Forms StackLayout.

Grid

Um Grid é usado para exibir elementos em linhas e colunas, que podem ter tamanhos proporcionais ou absolutos. As linhas e colunas de uma grade são especificadas com as RowDefinitions propriedades e ColumnDefinitions .

Para posicionar elementos em células específicas Grid , use as Grid.Column propriedades e Grid.Row anexadas. Para fazer com que os elementos se esteram entre várias linhas e colunas, use as Grid.RowSpan propriedades e Grid.ColumnSpan anexadas.

Observação

Um Grid layout não deve ser confundido com tabelas e não se destina a apresentar dados tabulares. Ao contrário das tabelas HTML, um Grid destina-se à distribuição de conteúdo. Para exibir dados tabulares, considere usar um ListView, CollectionView ou TableView.

O XAML a seguir mostra como criar um Grid com duas linhas e duas colunas:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>    
    <Label Text="Column 0, Row 0"
           WidthRequest="200" />
    <Label Grid.Column="1"
           Text="Column 1, Row 0" />
    <Label Grid.Row="1"
           Text="Column 0, Row 1" />
    <Label Grid.Column="1"
           Grid.Row="1"
           Text="Column 1, Row 1" />
</Grid>

Neste exemplo, o dimensionamento funciona da seguinte maneira:

  • Cada linha tem uma altura explícita de 50 unidades independentes do dispositivo.
  • A largura da primeira coluna é definida Autocomo e, portanto, é tão ampla quanto necessário para seus filhos. Nesse caso, são 200 unidades independentes do dispositivo de largura para acomodar a largura do primeiro Label.

O espaço pode ser distribuído em uma coluna ou linha usando o dimensionamento automático, o que permite que colunas e tamanho de linhas se ajustem ao conteúdo. Isso é obtido definindo a altura de um RowDefinitionou a largura de um ColumnDefinition, como Auto. O dimensionamento proporcional também pode ser usado para distribuir o espaço disponível entre as linhas e colunas da grade por proporções ponderadas. Isso é obtido definindo a altura de um RowDefinitionou a largura de um ColumnDefinition, para um valor que usa o * operador .

Cuidado

Tente garantir que o menor número possível de linhas e colunas esteja definido Auto como tamanho. Cada linha ou coluna dimensionada automaticamente fará o mecanismo de layout realizar cálculos de layout adicionais. Em vez disso, use linhas e colunas de tamanho fixo, se possível. Como alternativa, defina linhas e colunas para ocupar uma quantidade proporcional de espaço com o GridUnitType.Star valor de enumeração.

Para obter mais informações, consulte Xamarin.Forms Grade.

FlexLayout

Um FlexLayout é semelhante a um StackLayout em que exibe elementos filho horizontal ou verticalmente em uma pilha. No entanto, um FlexLayout também pode encapsular seus filhos se houver muitos para caber em uma única linha ou coluna, e também permite um controle mais granular do tamanho, orientação e alinhamento de seus elementos filho.

O XAML a seguir mostra como criar um FlexLayout que exibe seus modos de exibição em uma única coluna:

<FlexLayout Direction="Column"
            AlignItems="Center"
            JustifyContent="SpaceEvenly">
    <Label Text="FlexLayout in Action" />
    <Button Text="Button" />
    <Label Text="Another Label" />
</FlexLayout>

Neste exemplo, o layout funciona da seguinte maneira:

  • A Direction propriedade é definida Columncomo , o que faz com que os filhos do FlexLayout sejam organizados em uma única coluna de itens.
  • A AlignItems propriedade é definida como Center, o que faz com que cada item seja centralizado horizontalmente.
  • A JustifyContent propriedade é definida como SpaceEvenly, que aloca todo o espaço vertical restante igualmente entre todos os itens e acima do primeiro item e abaixo do último item.

Para obter mais informações, consulte Xamarin.Forms FlexLayout.

RelativeLayout

Um RelativeLayout é usado para posicionar e dimensionar elementos relativos às propriedades do layout ou dos elementos irmãos. Por padrão, um elemento é posicionado no canto superior esquerdo do layout. Um RelativeLayout pode ser usado para criar UIs que são dimensionadas proporcionalmente entre tamanhos de dispositivo.

Em um RelativeLayout, as posições e os tamanhos são especificados como restrições. As restrições têm Factor propriedades e Constant , que podem ser usadas para definir posições e tamanhos como múltiplos (ou frações) de propriedades de outros objetos, além de uma constante. Além disso, as constantes podem ser negativas.

Observação

Um RelativeLayout dá suporte ao posicionamento de elementos fora de seus próprios limites.

O XAML a seguir mostra como organizar elementos em um RelativeLayout:

<RelativeLayout>
    <BoxView Color="Blue"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView Color="Red"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.85}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView x:Name="pole"
             Color="Gray"
             WidthRequest="15"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.75}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.45}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.25}" />
    <BoxView Color="Green"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.10, Constant=10}"
             RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.2, Constant=20}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=X, Constant=15}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=Y, Constant=0}" />
</RelativeLayout>

Neste exemplo, o layout funciona da seguinte maneira:

  • O azul BoxView recebe um tamanho explícito de 50 x 50 unidades independentes do dispositivo. Ele é colocado no canto superior esquerdo do layout, que é a posição padrão.
  • O vermelho BoxView recebe um tamanho explícito de 50 x 50 unidades independentes do dispositivo. Ele é colocado no canto superior direito do layout.
  • O cinza BoxView recebe uma largura explícita de 15 unidades independentes do dispositivo e sua altura é definida como 75% da altura de seu pai.
  • O verde BoxView não tem um tamanho explícito. Sua posição é definida em relação ao BoxView chamado pole.

Aviso

Evite usar um RelativeLayout sempre que possível. Isso resultará em a CPU precisar realizar significativamente mais trabalho.

Para obter mais informações, consulte Xamarin.Forms RelativeLayout.

AbsoluteLayout

Um AbsoluteLayout é usado para posicionar e dimensionar elementos usando valores explícitos ou valores relativos ao tamanho do layout. A posição é especificada pelo canto superior esquerdo do filho em relação ao canto superior esquerdo do AbsoluteLayout.

Um AbsoluteLayout deve ser considerado como um layout de finalidade especial a ser usado somente quando você pode impor um tamanho para crianças ou quando o tamanho do elemento não afeta o posicionamento de outros filhos. Um uso padrão desse layout é criar uma sobreposição, que abrange a página com outros controles, talvez para proteger o usuário de interagir com os controles normais na página.

Importante

As HorizontalOptions propriedades e VerticalOptions não têm efeito em filhos de um AbsoluteLayout.

Em um AbsoluteLayout, a AbsoluteLayout.LayoutBounds propriedade anexada é usada para especificar a posição horizontal, a posição vertical, a largura e a altura de um elemento. Além disso, a AbsoluteLayout.LayoutFlags propriedade anexada especifica como os limites de layout serão interpretados.

O XAML a seguir mostra como organizar elementos em um AbsoluteLayout:

<AbsoluteLayout Margin="40">
    <BoxView Color="Red"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="30" />
    <BoxView Color="Green"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="60" />
    <BoxView Color="Blue"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" />
</AbsoluteLayout>

Neste exemplo, o layout funciona da seguinte maneira:

  • Cada BoxView um recebe um tamanho explícito de 100x100 e é exibido na mesma posição, centralizado horizontalmente.
  • O vermelho BoxView é girado 30 graus, e o verde BoxView é girado 60 graus.
  • Em cada BoxView, a AbsoluteLayout.LayoutFlags propriedade anexada é definida PositionProportionalcomo , indicando que a posição é proporcional ao espaço restante depois que a largura e a altura são contabilizados.

Cuidado

Evite usar a AbsoluteLayout.AutoSize propriedade sempre que possível, pois isso fará com que o mecanismo de layout execute cálculos de layout adicionais.

Para obter mais informações, consulte Xamarin.Forms AbsoluteLayout.

Transparência de entrada

Cada elemento visual tem uma InputTransparent propriedade usada para definir se o elemento recebe entrada. Seu valor padrão é false, garantindo que o elemento receba entrada.

Quando essa propriedade é definida em uma classe de layout, seu valor é transferido para elementos filho. Portanto, definir a InputTransparent propriedade como true em uma classe de layout resultará em todos os elementos dentro do layout não recebendo entrada.

Desempenho do layout

Para obter o melhor desempenho de layout possível, siga as diretrizes em Otimizar o desempenho do layout.

Além disso, o desempenho de renderização de página também pode ser aprimorado usando a compactação de layout, que remove os layouts especificados da árvore visual. Para obter mais informações, consulte Compactação de layout.