Especificar o tamanho de uma exibição

Concluído

É difícil criar uma interface do usuário que seja consistente entre vários dispositivos, porque eles podem ter tamanhos e densidades de pixel diferentes. Pense nos diferentes dispositivos disponíveis: celular, tablet, área de trabalho e assim por diante. Como criamos uma interface do usuário que tenha aparência semelhante em cada um?

A MAUI (interface do usuário do aplicativo multiplataforma) do .NET fornece painéis de layout para ajudá-lo a criar interfaces de usuário consistentes. O painel de layout é responsável por dimensionar e posicionar as exibições dos respectivos filhos. Nesta unidade, você aprenderá como o sistema de layout funciona no .NET MAUI. Em especial, examinaremos como as exibições são dimensionadas por padrão e como solicitar um tamanho e posição específicos para uma exibição em runtime.

O que é um painel de layout?

Um painel de layout é um contêiner do .NET MAUI que contém uma coleção de exibições filho e determina tamanho e posição delas. Os painéis de layout são recalculados automaticamente quando o tamanho do aplicativo é alterado; por exemplo, quando o usuário gira o dispositivo.

Observação

O termo exibição ou exibição filho se refere a um controle colocado em um painel de layout. Uma exibição pode ser uma etiqueta, um botão, um campo de entrada ou qualquer outro tipo de elemento visual compatível com o .NET MAUI.

O .NET MAUI tem vários painéis de layout entre os quais você pode escolher. Cada painel gerencia suas exibições filho de maneira diferente. A ilustração a seguir mostra uma visão geral conceitual de algumas das opções mais comuns.

Ilustração dos designs representativos de StackLayout, AbsoluteLayout, FlexLayout e Grid.

  • StackLayout: organiza as exibições filho em uma só linha ou coluna. Além de StackLayout, há também um VerticalStackLayout otimizado e HorizontalStackLayout quando você não precisa mudar de orientação.
  • AbsoluteLayout: organiza as respectivas exibições filho usando as coordenadas x e y.
  • Grid: organiza as respectivas exibições em células criadas com base na interseção de linhas e colunas.
  • FlexLayout: organiza as exibições filho como um StackLayout, exceto pelo fato de que você pode encapsulá-las se elas não se ajustarem a uma única linha ou coluna.

Observação

Também há um quinto tipo de painel de layout chamado RelativeLayout, que permite que você especifique como organizar exibições filho em relação umas às outras. Você deve usar o controle FlexLayout em vez de RelativeLayout porque ele tem um desempenho melhor. O RelativeLayout está incluído no .NET MAUI para compatibilidade com versões anteriores com aplicativos Xamarin mais antigos.

O processo típico para criar uma página do .NET MAUI é criar um painel de layout e adicionar exibições filho a ele. Quando você adiciona uma exibição a um layout, você pode influenciar o tamanho e a posição dele. No entanto, o painel tem a palavra final com base em seus algoritmos de layout internos.

Antes de você examinar como podemos solicitar um tamanho específico para uma exibição, veja como o sistema de layout dimensiona exibições por padrão.

Tamanho padrão de uma exibição

Se você não especificar o tamanho de uma exibição, ele aumentará automaticamente para ser exatamente grande o suficiente para se ajustar ao redor do respectivo conteúdo. Por exemplo, considere este XAML (Extensible Application Markup Language):

<Label
    Text="Hello"
    BackgroundColor="Silver"
    VerticalOptions="Center"
    HorizontalOptions="Center" 
    FontSize="40"/>

Este exemplo define uma etiqueta para exibir a palavra em Hello uma tela de fundo prata. Como você não está especificando o tamanho, a etiqueta será dimensionada automaticamente para se ajustar ao redor da palavra Hello. A imagem abaixo mostra a etiqueta renderizada em um dispositivo Android:

Captura de tela de um rótulo renderizado em um dispositivo Android que exibe a palavra “Olá” no centro com uma tela de fundo prateada.

Observação

Você pode definir a cor da tela de fundo da etiqueta para ajudar a determinar a largura dele em runtime. Essa uma boa técnica de depuração a se ter em mende quando você cria sua interface do usuário.

Especificar o tamanho de uma exibição

Quando você cria uma interface do usuário, é comum querer controlar o tamanho de uma exibição. Por exemplo, imagine que você esteja criando uma página de entrada e queira que o botão de entrada esteja exatamente no meio da largura da tela. Se você usasse o dimensionamento padrão para uma exibição, seu botão só seria do tamanho do texto Entrar. Esse tamanho não é grande o suficiente, então você mesmo precisa especificar o tamanho.

A classe base View define duas propriedades que influenciam no tamanho de uma exibição: WidthRequest e HeightRequest. WidthRequest permite que você especifique a largura e HeightRequest permite que você especifique a altura. Ambas as propriedades são do tipo double.

Veja um exemplo que mostra como especificar a largura e a altura de um rótulo em XAML:

<Label
    Text="Hello"
    BackgroundColor="Silver"
    VerticalOptions="Center"
    HorizontalOptions="Center"
    WidthRequest="100"
    HeightRequest="300"
    FontSize="40"/>

O resultado será semelhante a este:

Captura de tela de um rótulo renderizado em um dispositivo Android que exibe a palavra “Olá” no centro com uma tela de fundo prateada. O rótulo está dimensionado explicitamente

Observação

A etiqueta ainda está centralizada, embora o texto da etiqueta não esteja no centro dela.

Uma coisa que vale a pena observar são os nomes dessas propriedades. Ambas as propriedades contêm a palavra solicitação. Essa palavra significa que o painel de layout pode não respeitá-las em runtime. O painel de layout lê esses valores durante seus cálculos de dimensionamento e tenta acomodar as solicitações, se possível. Se não há espaço suficiente, o painel de layout tem permissão para ignorar os valores.

Unidades de tamanho

Quando você define WidthRequest e HeightRequest, você usa valores literais como 100. No nível do .NET MAUI, esses valores não têm unidades. Eles não são pontos nem pixels. São apenas valores do tipo double. O .NET MAUI passa esses valores para o sistema operacional subjacente em runtime. É o sistema operacional que oferece o contexto necessário para determinar o que esses números significam:

  • No iOS, os valores são chamados pontos.
  • No Android, são pixels independentes de densidade.

Tamanho renderizado de uma exibição

Como cabe ao painel de layout determinar o tamanho de uma exibição, não é possível usar WidthRequest nem HeightRequest para informar o tamanho real em runtime. Por exemplo, imagine que você definiu WidthRequest como 100 para seu rótulo, mas o painel não tem espaço suficiente para atender à solicitação. Em vez disso, o painel oferece ao seu rótulo uma largura de 80. Nesse momento, se você verificar o valor da propriedade WidthRequest, ele indicará 100 mesmo que o valor renderizado seja 80.

Para resolver esse problema, a classe base View define duas propriedades adicionais chamadas Width e Height. Essas propriedades são do tipo double e representam a largura e a altura renderizadas de uma exibição. Use as propriedades Width e Height sempre que recuperar o tamanho de uma exibição.

Especificar a posição de uma exibição

Também é necessário definir a posição de uma exibição. Por exemplo, lembre-se de que, no exemplo da página de entrada, queríamos dimensionar o botão de entrada para ocupar metade da largura da tela. Como o botão de logon não ocupa toda a largura da tela, há algum espaço disponível para movê-lo. Você poderia posicioná-lo do lado esquerdo, do lado direito ou no centro da tela.

A classe base View define duas propriedades que você usa para definir a posição de uma exibição: VerticalOptions e HorizontalOptions. Essas configurações influenciam a maneira como a exibição é posicionada dentro do retângulo alocado para ela pelo painel de layout. É possível especificar se você deseja que a exibição se alinhe a uma das quatro bordas do retângulo. Ou então, que você quer que ele ocupe todo o retângulo.

Especificar um valor para VerticalOptions ou HorizontalOptions é mais desafiador do que definir o tamanho, porque eles são do tipo LayoutOptions.

O que é o tipo LayoutOptions?

LayoutOptions é um tipo de C# que encapsula duas preferências de layout, Alignment e Expands. As duas propriedades estão relacionadas ao posicionamento, mas elas não estão relacionadas entre si. Veja qual é a aparência da definição do tipo:

public struct LayoutOptions
{
    public LayoutAlignment Alignment { get; set; }
    public bool Expands { get; set; }
    ...
}

Em seguida, analisamos Alignment mais de perto porque essa é a opção de layout mais comum e intuitiva.

O que é a enumeração LayoutAlignment?

LayoutAlignment é uma enumeração que contém quatro valores: Start, Center, End e Fill. É possível usar esses valores para controlar como a exibição filho é posicionada dentro do retângulo fornecido a ela por seu painel de layout. Por exemplo, considere o seguinte código e a captura de tela do Android:

<StackLayout>
    <Label Text="Start" HorizontalOptions="Start" BackgroundColor="Silver" FontSize="40" />
    <Label Text="Center" HorizontalOptions="Center" BackgroundColor="Silver"  FontSize="40" />
    <Label Text="End" HorizontalOptions="End" BackgroundColor="Silver"  FontSize="40"/>
    <Label Text="Fill" HorizontalOptions="Fill" BackgroundColor="Silver"  FontSize="40"/>
</StackLayout>

Captura de tela mostrando quatro rótulos renderizados no iOS com diferentes HorizontalOptions: Comece no lado esquerdo, Centralize centralizado, Fim no lado direito e Preencha abrangendo a tela inteira.

O exemplo usa um StackLayout vertical e, portanto, cada exibição filho recebe uma linha. HorizontalOptions determina a posição da exibição dentro de sua linha.

O que é Expands?

A segunda propriedade do struct LayoutOptions é Expands. A propriedade Expands é um bool que permitia que uma exibição em um StackLayout no Xamarin.forms solicitasse espaço extra, caso disponível. Essa propriedade agora está obsoleta e não é mais usada no .NET MAUI. Depois, vemos como obter o mesmo tipo de expansão na unidade no layout Grid.

Verificação de conhecimentos

1.

O que um LayoutPanel faz?