Partilhar via


Escolha um Xamarin.Forms layout

Xamarin.Forms As classes de layout permitem que você organize e agrupe controles de interface do usuário em seu aplicativo. A escolha de 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 principais Xamarin.Forms :

As principais classes de layout em Xamarin.Forms

StackLayout

A 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 uma 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 for definido explicitamente, ele se expandirá para preencher a largura ou altura disponível se a Orientation propriedade estiver definida como Horizontal.

A StackLayout é frequentemente usado como um layout pai, que contém outros layouts filho. No entanto, a 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 ruim:

<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 alcançado usando um Grid.

Dica

Ao usar um StackLayout, certifique-se de que apenas um elemento filho esteja 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.

Grade

A 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 estendam por 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, a Grid destina-se ao layout do 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 de dispositivo.
  • A largura da primeira coluna é definida como Auto, e, portanto, é tão larga quanto necessário para seus filhos. Nesse caso, são 200 unidades independentes de dispositivo de largura para acomodar a largura do primeiro Label.

O espaço pode ser distribuído dentro de uma coluna ou linha usando o dimensionamento automático, que permite que o tamanho das colunas e linhas se ajuste ao seu conteúdo. Isso é obtido definindo a altura de um RowDefinition, ou a largura de um ColumnDefinition, para 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 RowDefinition, ou 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 seja definido como Auto 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

A FlexLayout é semelhante a a StackLayout , pois 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 suas exibições 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 como Column, o FlexLayout que faz com que os filhos do 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, acima do primeiro item e abaixo do último item.

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

RelativeLayout

A RelativeLayout é usado para posicionar e dimensionar elementos em relação às propriedades do layout ou dos elementos irmãos. Por padrão, um elemento é posicionado no canto superior esquerdo do layout. A RelativeLayout pode ser usado para criar interfaces do usuário que são dimensionadas proporcionalmente entre os tamanhos dos dispositivos.

Dentro de um RelativeLayout, posições e 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

A RelativeLayout suporta o 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 50x50 unidades independentes de dispositivo. Ele é colocado no canto superior esquerdo do layout, que é a posição padrão.
  • O vermelho BoxView recebe um tamanho explícito de 50x50 unidades independentes de dispositivo. Ele é colocado no canto superior direito do layout.
  • O cinza BoxView recebe uma largura explícita de 15 unidades independentes de dispositivo e sua altura é definida como 75% da altura de seu pai.
  • O verde BoxView não recebe um tamanho explícito. Sua posição é definida em relação ao BoxView nome 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

An 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.

An AbsoluteLayout deve ser considerado como um layout de propósito especial a ser usado somente quando você pode impor um tamanho às crianças ou quando o tamanho do elemento não afeta o posicionamento de outras crianças. Um uso padrão desse layout é criar uma sobreposição, que cobre 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 sobre os filhos de um AbsoluteLayout.

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

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

<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 propriedade anexada AbsoluteLayout.LayoutFlags é definida como PositionProportional, indicando que a posição é proporcional ao espaço restante depois que a largura e a altura são contabilizadas.

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 que é 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 fará com que todos os elementos dentro do layout não recebam 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 da renderização de página também pode ser melhorado usando a compactação de layout, que remove layouts especificados da árvore visual. Para obter mais informações, consulte Compactação de layout.