Xamarin.Forms RelativeLayout

Xamarin.Forms RelativeLayout

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 sejam dimensionadas proporcionalmente entre os tamanhos de dispositivo. Além disso, ao contrário de algumas outras classes de layout, RelativeLayout é capaz de posicionar as crianças de modo 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 da criança.
  • 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 da criança.
  • 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 de XAML.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que as propriedades podem ser alvos 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 um RelativeLayout também podem ser especificadas por meio das propriedades e HeightRequestWidthRequest da criança, em vez das WidthConstraint propriedades anexadasHeightConstraint.

A RelativeLayout classe deriva da Layout<T> classe, que define uma Children propriedade do tipo IList<T>. A Children propriedade é a ContentProperty da Layout<T> classe e, portanto, não precisa ser definida explicitamente a partir de 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 são especificadas, uma criança será posicionada 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 propriedades anexadas RelativeLayout 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 propriedades anexadas RelativeLayout para 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.

No C#, as crianças podem ser adicionadas por RelativeLayout três Add sobrecargas. A primeira sobrecarga requer um Expression<Func<Rectangle>> para especificar a posição e o tamanho de uma criança. A segunda sobrecarga requer objetos opcionais Expression<Func<double>> para os xargumentos , ywidth, e height . A terceira sobrecarga requer objetos opcionais Constraint para os xargumentos , ywidth, e height .

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

Posicionamento e dimensionamento absolutos

A RelativeLayout pode posicionar e dimensionar filhos 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 a RelativeLayout e definindo as XConstraintpropriedades , YConstraintWidthConstraint, 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 tamanhos e resoluções de tela diferentes. 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 sã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 anexadas e HeightConstraint anexadas. A posição do Label objeto também é definida usando os valores especificados nas XConstraint propriedades anexadas e YConstraint . No entanto, os valores de tamanho não são especificados para o Label, e, portanto, ele é irrestrito e dimensiona-se. Em todos os casos, os valores absolutos representam unidades independentes do dispositivo.

As capturas de tela a seguir mostram o layout resultante:

Crianças colocadas 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 objetos são adicionados ao uso de RelativeLayout 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 relativo e dimensionamento

A RelativeLayout pode posicionar e dimensionar filhos usando valores relativos às propriedades do layout ou elementos irmãos. Isso é obtido adicionando filhos à coleção das RelativeLayout propriedades , YConstraintWidthConstraint, e HeightConstraint anexadas XConstraintem cada filho para valores relativos usando ConstraintChildren objetos.

As restrições podem ser uma constante, em relação a um pai ou 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 um modo de exibição (ou irmão).
  • Constant, 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 com seu pai ou com um irmão.

A classe ConstraintExpression define as seguintes propriedades:

  • Constant, do tipo double, que representa o valor constante de restrição.
  • ElementName, do tipo string, que representa o nome de um elemento de origem em relação ao 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 fonte. Essa propriedade tem como padrão 1.
  • Property, do tipo string, que representa o nome da propriedade no elemento source a ser usado no cálculo de 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 restringidos 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 anexadas definidas YConstraint 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 propriedade anexada YConstraint 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. Ele 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 propriedades e HeightConstraint anexadas YConstraint são definidas para a altura do pai, multiplicadas por 0,33.

O preto BoxView é posicionado e dimensionado oneThirdBoxViewem relação ao . Isso é conseguido definindo suas XConstraint propriedades e YConstraint anexadas aos X valores e Y valores, 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 é conseguido definindo suas WidthConstraint propriedades e HeightConstraint anexadas Width aos valores e Height valores do elemento irmão, respectivamente, que são então multiplicados por 0,33.

A captura de tela a seguir mostra o layout resultante:

Crianças colocadas 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 uma criança 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 propriedade anexada BoundsConstraint .

O código C# a seguir mostra um RelativeLayout cujos filhos são restringidos 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 filhos são adicionados ao uso da Add sobrecarga que requer um objeto opcional Constraint para os xargumentos , ywidth, e height .RelativeLayout

Observação

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