Xamarin.Forms Layout absoluto

Xamarin.Forms Layout absoluto

An AbsoluteLayout é usado para posicionar e dimensionar filhos usando valores explícitos. A posição é especificada pelo canto superior esquerdo do filho em relação ao canto superior esquerdo do , em unidades independentes do AbsoluteLayoutdispositivo. AbsoluteLayout também implementa um recurso de posicionamento e dimensionamento proporcional. Além disso, ao contrário de algumas outras classes de layout, AbsoluteLayout é capaz de posicionar filhos para que eles se sobreponham.

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.

A classe AbsoluteLayout define as seguintes propriedades:

  • LayoutBounds, do tipo Rectangle, que é uma propriedade anexada que representa a posição e o tamanho de um filho. O valor padrão dessa propriedade é (0,0,AutoSize,AutoSize).
  • LayoutFlags, do tipo AbsoluteLayoutFlags, que é uma propriedade anexada que indica se as propriedades dos limites de layout usados para posicionar e dimensionar o filho são interpretadas proporcionalmente. O valor padrão dessa propriedade é AbsoluteLayoutFlags.None.

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.

A AbsoluteLayout 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

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

Posição e tamanho das crianças

A posição e o tamanho das crianças em um AbsoluteLayout são definidos definindo a propriedade anexada AbsoluteLayout.LayoutBounds de cada criança, usando valores absolutos ou valores proporcionais. Valores absolutos e proporcionais podem ser misturados para crianças quando a posição deve ser dimensionada, mas o tamanho deve permanecer fixo ou vice-versa. Para obter informações sobre valores absolutos, consulte Posicionamento e dimensionamento absolutos. Para obter informações sobre valores proporcionais, consulte Posicionamento e dimensionamento proporcionais.

A AbsoluteLayout.LayoutBounds propriedade anexada pode ser definida usando dois formatos, independentemente de valores absolutos ou proporcionais serem usados:

  • x, y. Com esse formato, os x valores e y indicam a posição do canto superior esquerdo do filho em relação ao pai. A criança é irrestrita e se dimensiona.
  • x, y, width, height. Com esse formato, os x valores e y indicam a posição do canto superior esquerdo do filho em relação ao pai, enquanto os width valores e height indicam o tamanho do filho.

Para especificar que um filho se dimensiona horizontalmente ou verticalmente, ou ambos, defina os width valores e/ou height para a AbsoluteLayout.AutoSize propriedade. No entanto, o uso excessivo dessa propriedade pode prejudicar o desempenho do aplicativo, pois faz com que o mecanismo de layout execute cálculos de layout adicionais.

Importante

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

Posicionamento e dimensionamento absolutos

Por padrão, um AbsoluteLayout posiciona e dimensiona filhos usando valores absolutos, especificados em unidades independentes de dispositivo, que definem explicitamente onde os filhos devem ser colocados no layout. Isso é obtido adicionando filhos à Children coleção de um AbsoluteLayout e definindo a propriedade anexada AbsoluteLayout.LayoutBounds 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 AbsoluteLayout 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="AbsoluteLayoutDemos.Views.StylishHeaderDemoPage"
             Title="Stylish header demo">
    <AbsoluteLayout Margin="20">
        <BoxView Color="Silver"
                 AbsoluteLayout.LayoutBounds="0, 10, 200, 5" />
        <BoxView Color="Silver"
                 AbsoluteLayout.LayoutBounds="0, 20, 200, 5" />
        <BoxView Color="Silver"
                 AbsoluteLayout.LayoutBounds="10, 0, 5, 65" />
        <BoxView Color="Silver"
                 AbsoluteLayout.LayoutBounds="20, 0, 5, 65" />
        <Label Text="Stylish Header"
               FontSize="24"
               AbsoluteLayout.LayoutBounds="30, 25" />
    </AbsoluteLayout>
</ContentPage>

Neste exemplo, a posição de cada BoxView objeto é definida usando os dois primeiros valores absolutos especificados na AbsoluteLayout.LayoutBounds propriedade anexada. O tamanho de cada um BoxView é definido usando os valores terceiro e quarto. A posição do Label objeto é definida usando os dois valores absolutos especificados na AbsoluteLayout.LayoutBounds propriedade anexada. 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.

A captura de tela a seguir mostra o layout resultante:

Filhos colocados em um AbsoluteLayout usando valores absolutos

O código C# equivalente é mostrado abaixo:

public class StylishHeaderDemoPageCS : ContentPage
{
    public StylishHeaderDemoPageCS()
    {
        AbsoluteLayout absoluteLayout = new AbsoluteLayout
        {
            Margin = new Thickness(20)
        };

        absoluteLayout.Children.Add(new BoxView
        {
            Color = Color.Silver,
        }, new Rectangle(0, 10, 200, 5));
        absoluteLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, new Rectangle(0, 20, 200, 5));
        absoluteLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, new Rectangle(10, 0, 5, 65));
        absoluteLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, new Rectangle(20, 0, 5, 65));

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

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

Neste exemplo, a posição e o tamanho de cada um BoxView são definidos usando um Rectangle objeto. A posição do Label é definida usando um Point objeto.

Em C#, também é possível definir a posição e o tamanho de um filho de um AbsoluteLayout depois que ele foi adicionado à Children coleção, usando o AbsoluteLayout.SetLayoutBounds método. O primeiro argumento para esse método é o filho e o segundo é um Rectangle objeto.

Observação

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

Posicionamento e dimensionamento proporcionais

Um AbsoluteLayout pode posicionar e dimensionar crianças usando valores proporcionais. Isso é obtido adicionando filhos à Children coleção do AbsoluteLayout, e definindo a propriedade anexada AbsoluteLayout.LayoutBounds em cada filho para valores proporcionais de posição e/ou tamanho no intervalo de 0 a 1. Os valores de posição e tamanho são proporcionais definindo a propriedade anexada AbsoluteLayout.LayoutFlags em cada filho.

A AbsoluteLayout.LayoutFlags propriedade anexada, do tipo AbsoluteLayoutFlags, permite que você defina um sinalizador que indica que os limites de layout e os valores de tamanho de um filho são proporcionais ao tamanho do AbsoluteLayout. Ao criar o layout de um filho, AbsoluteLayout dimensiona os valores de posição e tamanho adequadamente, para qualquer tamanho de dispositivo.

A enumeração AbsoluteLayoutFlags define os seguintes membros:

  • None, indica que os valores serão interpretados como absolutos. Esse é o valor padrão da propriedade anexada AbsoluteLayout.LayoutFlags.
  • XProportional, indica que o x valor será interpretado como proporcional, enquanto trata todos os outros valores como absolutos.
  • YProportional, indica que o y valor será interpretado como proporcional, enquanto trata todos os outros valores como absolutos.
  • WidthProportional, indica que o width valor será interpretado como proporcional, enquanto trata todos os outros valores como absolutos.
  • HeightProportional, indica que o height valor será interpretado como proporcional, enquanto trata todos os outros valores como absolutos.
  • PositionProportional, indica que os x valores e y serão interpretados como proporcionais, enquanto os valores de tamanho são interpretados como absolutos.
  • SizeProportional, indica que os width valores e height serão interpretados como proporcionais, enquanto os valores de posição são interpretados como absolutos.
  • All, indica que todos os valores serão interpretados como proporcionais.

Dica

A AbsoluteLayoutFlags enumeração é uma Flags enumeração, o que significa que os membros da enumeração podem ser combinados. Isso é feito em XAML com uma lista separada por vírgulas e em C# com o operador OR bit a bit.

Por exemplo, se você usar o SizeProportional sinalizador e definir a largura de um filho como 0,25 e a altura como 0,1, o filho terá um quarto da largura e AbsoluteLayout um décimo da altura. A PositionProportional bandeira é semelhante. Uma posição de (0,0) coloca a criança no canto superior esquerdo, enquanto uma posição de (1,1) coloca a criança no canto inferior direito e uma posição de (0,5,0,5) centraliza a criança dentro do AbsoluteLayout.

O XAML a seguir mostra um AbsoluteLayout cujos filhos estão posicionados usando valores proporcionais:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AbsoluteLayoutDemos.Views.ProportionalDemoPage"
             Title="Proportional demo">
    <AbsoluteLayout>
        <BoxView Color="Blue"
                 AbsoluteLayout.LayoutBounds="0.5,0,100,25"
                 AbsoluteLayout.LayoutFlags="PositionProportional" />
        <BoxView Color="Green"
                 AbsoluteLayout.LayoutBounds="0,0.5,25,100"
                 AbsoluteLayout.LayoutFlags="PositionProportional" />
        <BoxView Color="Red"
                 AbsoluteLayout.LayoutBounds="1,0.5,25,100"
                 AbsoluteLayout.LayoutFlags="PositionProportional" />
        <BoxView Color="Black"
                 AbsoluteLayout.LayoutBounds="0.5,1,100,25"
                 AbsoluteLayout.LayoutFlags="PositionProportional" />
        <Label Text="Centered text"
               AbsoluteLayout.LayoutBounds="0.5,0.5,110,25"
               AbsoluteLayout.LayoutFlags="PositionProportional" />
    </AbsoluteLayout>
</ContentPage>

Neste exemplo, cada filho é posicionado usando valores proporcionais, mas dimensionado usando valores absolutos. Isso é feito definindo a propriedade anexada AbsoluteLayout.LayoutFlags de cada filho como PositionProportional. Os dois primeiros valores especificados na AbsoluteLayout.LayoutBounds propriedade anexada, para cada filho, definem a posição usando valores proporcionais. O tamanho de cada criança é definido com o terceiro e quarto valores absolutos, usando unidades independentes do dispositivo.

A captura de tela a seguir mostra o layout resultante:

Filhos colocados em um AbsoluteLayout usando valores de posição proporcionais

O código C# equivalente é mostrado abaixo:

public class ProportionalDemoPageCS : ContentPage
{
    public ProportionalDemoPageCS()
    {
        BoxView blue = new BoxView { Color = Color.Blue };
        AbsoluteLayout.SetLayoutBounds(blue, new Rectangle(0.5, 0, 100, 25));
        AbsoluteLayout.SetLayoutFlags(blue, AbsoluteLayoutFlags.PositionProportional);

        BoxView green = new BoxView { Color = Color.Green };
        AbsoluteLayout.SetLayoutBounds(green, new Rectangle(0, 0.5, 25, 100));
        AbsoluteLayout.SetLayoutFlags(green, AbsoluteLayoutFlags.PositionProportional);

        BoxView red = new BoxView { Color = Color.Red };
        AbsoluteLayout.SetLayoutBounds(red, new Rectangle(1, 0.5, 25, 100));
        AbsoluteLayout.SetLayoutFlags(red, AbsoluteLayoutFlags.PositionProportional);

        BoxView black = new BoxView { Color = Color.Black };
        AbsoluteLayout.SetLayoutBounds(black, new Rectangle(0.5, 1, 100, 25));
        AbsoluteLayout.SetLayoutFlags(black, AbsoluteLayoutFlags.PositionProportional);

        Label label = new Label { Text = "Centered text" };
        AbsoluteLayout.SetLayoutBounds(label, new Rectangle(0.5, 0.5, 110, 25));
        AbsoluteLayout.SetLayoutFlags(label, AbsoluteLayoutFlags.PositionProportional);

        Title = "Proportional demo";
        Content = new AbsoluteLayout
        {
            Children = { blue, green, red, black, label }
        };
    }
}

Neste exemplo, a posição e o tamanho de cada filho são definidos com o AbsoluteLayout.SetLayoutBounds método. O primeiro argumento para o método é o filho e o segundo é um Rectangle objeto. A posição de cada criança é definida com valores proporcionais, enquanto o tamanho de cada criança é definido com valores absolutos, usando unidades independentes do dispositivo.

Observação

Um AbsoluteLayout que usa valores proporcionais pode posicionar e dimensionar filhos para que eles não caibam dentro dos limites do layout usando valores fora do intervalo de 0 a 1.