Compartilhar via


Xamarin.Forms Layout Relativo

Xamarin.Forms Layout Relativo

A RelativeLayout é usado para posicionar e dimensionar filhos em relação às propriedades do layout ou dos elementos irmãos. Isso permite que sejam criadas interfaces do usuário que são dimensionadas proporcionalmente entre os tamanhos dos dispositivos. Além disso, ao contrário de algumas outras classes de layout, RelativeLayout é capaz de posicionar filhos para que se sobreponham.

A classe RelativeLayout define as seguintes propriedades:

  • XConstraint, do tipo Constraint, que é uma propriedade anexada que representa a restrição na posição X do filho.
  • YConstraint, do tipo Constraint, que é uma propriedade anexada que representa a restrição na posição Y do filho.
  • WidthConstraint, do tipo Constraint, que é uma propriedade anexada que representa a restrição na largura do filho.
  • HeightConstraint, do tipo Constraint, que é uma propriedade anexada que representa a restrição na altura do filho.
  • BoundsConstraint, do tipo BoundsConstraint, que é uma propriedade anexada que representa a restrição na posição e no tamanho do filho. Essa propriedade não pode ser facilmente consumida do XAML.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que as propriedades podem ser destinos de associações de dados e estilizadas. Para obter mais informações sobre propriedades anexadas, consulte Xamarin.Forms Propriedades anexadas.

Observação

A largura e a altura de um filho em a RelativeLayout também podem ser especificadas WidthRequest por meio das propriedades and HeightRequest do filho, em vez das WidthConstraint propriedades e HeightConstraint anexadas.

A RelativeLayout classe deriva da Layout<T> classe, que define uma Children propriedade do tipo IList<T>. A propriedade Children é o ContentProperty da classe Layout<T> e, portanto, não precisa ser definida explicitamente no XAML.

Dica

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

Restrições

Dentro de um RelativeLayout, a posição e o tamanho dos filhos são especificados como restrições usando valores absolutos ou valores relativos. Quando as restrições não forem especificadas, um filho será posicionado no canto superior esquerdo do layout.

A tabela a seguir mostra como especificar restrições em XAML e C#:

XAML C#
Valores absolutos As restrições absolutas são especificadas definindo as RelativeLayout propriedades anexadas como double valores. As restrições absolutas são especificadas pelo Constraint.Constant método ou usando a Children.Add sobrecarga que requer um Func<Rectangle> argumento.
Valores relativos As restrições relativas são especificadas definindo as RelativeLayout propriedades anexadas aos Constraint objetos que são retornados pela extensão de ConstraintExpression marcação. As restrições relativas são especificadas por Constraint objetos que são retornados por métodos da Constraint classe.

Para obter mais informações sobre como especificar restrições usando valores absolutos, consulte Posicionamento e dimensionamento absolutos. Para obter mais informações sobre como especificar restrições usando valores relativos, consulte Posicionamento e dimensionamento relativos.

Em C#, os filhos podem ser adicionados por RelativeLayout três Add sobrecargas. A primeira sobrecarga requer a Expression<Func<Rectangle>> para especificar a posição e o tamanho de um filho. A segunda sobrecarga requer objetos opcionais Expression<Func<double>> para os xargumentos , y, width, e height . A terceira sobrecarga requer objetos opcionais Constraint para os xargumentos , y, width, e height .

É possível alterar a posição e o tamanho de uma criança em a RelativeLayout com os SetXConstraintmétodos , SetYConstraint, SetWidthConstraint, e SetHeightConstraint . O primeiro argumento para cada um desses métodos é o filho e o segundo é um Constraint objeto. Além disso, o SetBoundsConstraint método também pode ser usado para alterar a posição e o tamanho de uma criança. O primeiro argumento para esse método é o filho e o segundo é um BoundsConstraint objeto.

Posicionamento e dimensionamento absolutos

Um RelativeLayout pode posicionar e dimensionar crianças usando valores absolutos, especificados em unidades independentes de dispositivo, que definem explicitamente onde as crianças devem ser colocadas no layout. Isso é obtido adicionando filhos à Children coleção de um RelativeLayout e definindo as XConstraintpropriedades , YConstraint, WidthConstraint, e HeightConstraint anexadas em cada filho para valores absolutos de posição e/ou tamanho.

Aviso

Usar valores absolutos para posicionar e dimensionar crianças pode ser problemático, porque diferentes dispositivos têm diferentes tamanhos e resoluções de tela. Portanto, as coordenadas para o centro da tela em um dispositivo podem ser deslocadas em outros dispositivos.

O XAML a seguir mostra um RelativeLayout cujos filhos estão posicionados usando valores absolutos:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.StylishHeaderDemoPage"
             Title="Stylish header demo">
    <RelativeLayout Margin="20">
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="10"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="20"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="10"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="20"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <Label Text="Stylish header"
               FontSize="24"
               RelativeLayout.XConstraint="30"
               RelativeLayout.YConstraint="25" />
    </RelativeLayout>
</ContentPage>

Neste exemplo, a posição de cada BoxView objeto é definida usando os valores especificados nas XConstraint propriedades e YConstraint anexadas. O tamanho de cada um BoxView é definido usando os valores especificados nas WidthConstraint propriedades e HeightConstraint anexadas. A posição do Label objeto também é definida usando os valores especificados nas XConstraint propriedades e YConstraint anexadas. No entanto, os valores de tamanho não são especificados para o Label, e, portanto, ele não é restrito e se dimensiona. Em todos os casos, os valores absolutos representam unidades independentes do dispositivo.

As capturas de tela a seguir mostram o layout resultante:

Filhos colocados em um RelativeLayout usando valores absolutos

O código C# equivalente é mostrado abaixo:

public class StylishHeaderDemoPageCS : ContentPage
{
    public StylishHeaderDemoPageCS()
    {
        RelativeLayout relativeLayout = new RelativeLayout
        {
            Margin = new Thickness(20)
        };

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 10, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 20, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(10, 0, 5, 65));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(20, 0, 5, 65));

        relativeLayout.Children.Add(new Label
        {
            Text = "Stylish Header",
            FontSize = 24
        }, Constraint.Constant(30), Constraint.Constant(25));

        Title = "Stylish header demo";
        Content = relativeLayout;
    }
}

Neste exemplo, BoxView os RelativeLayout objetos são adicionados ao usando uma Add sobrecarga que requer um Expression<Func<Rectangle>> para especificar a posição e o tamanho de cada filho. A posição do Label é definida usando uma Add sobrecarga que requer objetos opcionais Constraint , neste caso criados pelo Constraint.Constant método.

Observação

Um RelativeLayout que usa valores absolutos pode posicionar e dimensionar filhos para que eles não caibam dentro dos limites do layout.

Posicionamento e dimensionamento relativos

A RelativeLayout pode posicionar e dimensionar filhos usando valores relativos às propriedades do layout ou elementos irmãos. Isso é feito adicionando filhos à Children coleção do RelativeLayout e definindo as XConstraintpropriedades , YConstraint, WidthConstraint, e HeightConstraint attached em cada filho para valores relativos usando Constraint objetos.

As restrições podem ser uma constante, em relação a um pai ou em relação a um irmão. O tipo de restrição é representado pela ConstraintType enumeração, que define os seguintes membros:

  • RelativeToParent, que indica uma restrição relativa a um pai.
  • RelativeToView, que indica uma restrição relativa a uma exibição (ou irmã).
  • Constant, o que indica uma restrição constante.

Extensão de marcação de restrição

Em XAML, um Constraint objeto pode ser criado pela extensão de ConstraintExpression marcação. Essa extensão de marcação é normalmente usada para relacionar a posição e o tamanho de uma criança dentro de um RelativeLayout para seu pai ou para um irmão.

A classe ConstraintExpression define as seguintes propriedades:

  • Constant, do tipo double, que representa o valor da constante de restrição.
  • ElementName, do tipo string, que representa o nome de um elemento de origem no qual calcular a restrição.
  • Factor, do tipo double, que representa o fator pelo qual dimensionar uma dimensão restrita, em relação ao elemento de origem. O padrão dessa propriedade é 1.
  • Property, do tipo string, que representa o nome da propriedade no elemento de origem a ser usado no cálculo da restrição.
  • Type, do tipo ConstraintType, que representa o tipo da restrição.

Para obter mais informações sobre Xamarin.Forms extensões de marcação, consulte Extensões de marcação XAML.

O XAML a seguir mostra um RelativeLayout cujos filhos são restritos pela extensão de ConstraintExpression marcação:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.RelativePositioningAndSizingDemoPage"
             Title="RelativeLayout demo">
    <RelativeLayout>
        <BoxView Color="Red"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Green"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Blue"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />
        <BoxView Color="Yellow"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />

        <!-- Centered and 1/3 width and height of parent -->
        <BoxView x:Name="oneThird"
                 Color="Silver"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}" />

        <!-- 1/3 width and height of previous -->
        <BoxView Color="Black"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=X}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Y}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Height, Factor=0.33}" />
    </RelativeLayout>
</ContentPage>

Neste exemplo, a posição de cada BoxView objeto é definida definindo as XConstraint propriedades e YConstraint anexadas. O primeiro BoxView tem suas XConstraint propriedades e YConstraint anexadas definidas como constantes, que são valores absolutos. Todos os objetos restantes BoxView têm sua posição definida usando pelo menos um valor relativo. Por exemplo, o objeto amarelo BoxView define a propriedade anexada XConstraint para a largura de seu pai (o RelativeLayout) menos 40. Da mesma forma, isso BoxView define a YConstraint propriedade anexada para a altura de seu pai menos 40. Isso garante que o amarelo BoxView apareça no canto inferior direito da tela.

Observação

BoxView Os objetos que não especificam um tamanho são dimensionados automaticamente para 40x40 por Xamarin.Forms.

A prata BoxView nomeada oneThird é posicionada centralmente, em relação ao seu pai. Também é dimensionado em relação ao seu pai, sendo um terço de sua largura e altura. Isso é obtido definindo as XConstraint propriedades e WidthConstraint anexadas para a largura do pai (o RelativeLayout), multiplicado por 0,33. Da mesma forma, as YConstraint propriedades e HeightConstraint anexadas são definidas como a altura do pai, multiplicada por 0,33.

O preto BoxView é posicionado e dimensionado oneThird BoxViewem relação ao . Isso é obtido definindo suas XConstraint propriedades e YConstraint anexadas aos X valores e Y , respectivamente, do elemento irmão. Da mesma forma, seu tamanho é definido como um terço da largura e altura de seu elemento irmão. Isso é obtido definindo suas WidthConstraint propriedades e HeightConstraint anexadas aos Width valores e Height do elemento irmão, respectivamente, que são então multiplicados por 0,33.

A captura de tela a seguir mostra o layout resultante:

Filhos colocados em um RelativeLayout usando valores relativos

Objetos de restrição

A Constraint classe define os seguintes métodos estáticos públicos, que retornam Constraint objetos:

  • Constant, que restringe uma criança a um tamanho especificado com um double.
  • FromExpression, que restringe uma criança usando uma expressão lambda.
  • RelativeToParent, que restringe uma criança em relação ao tamanho de seus pais.
  • RelativeToView, que restringe um filho em relação ao tamanho de uma exibição.

Além disso, a BoundsConstraint classe define um único método, FromExpression, que retorna um que restringe a BoundsConstraint posição e o tamanho de uma criança com um Expression<Func<Rectangle>>. Esse método pode ser usado para definir a BoundsConstraint propriedade anexada.

O código C# a seguir mostra um RelativeLayout cujos filhos são restritos por Constraint objetos:

public class RelativePositioningAndSizingDemoPageCS : ContentPage
{
    public RelativePositioningAndSizingDemoPageCS()
    {
        RelativeLayout relativeLayout = new RelativeLayout();

        // Four BoxView's
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Red },
            Constraint.Constant(0),
            Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Green },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }), Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Blue },
            Constraint.Constant(0),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Yellow },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        // Centered and 1/3 width and height of parent
        BoxView silverBoxView = new BoxView { Color = Color.Silver };
        relativeLayout.Children.Add(
            silverBoxView,
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }));

        // 1/3 width and height of previous
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Black },
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.X;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Y;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Width * 0.33;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Height * 0.33;
            }));

        Title = "RelativeLayout demo";
        Content = relativeLayout;
    }
}

Neste exemplo, os RelativeLayout filhos são adicionados ao usando a Add sobrecarga que requer um objeto opcional Constraint para os xargumentos , y, width, e height .

Observação

Um RelativeLayout que usa valores relativos pode posicionar e dimensionar filhos para que eles não caibam dentro dos limites do layout.