Контейнер AbsoluteLayout позволяет установить для вложенных элементов точные размеры и координаты расположения на странице.
Для установки размеров и позиционирования вложенных элементов AbsoluteLayout определяет два свойства:
LayoutBounds: представляет объект типа Rect (прямоугольная область), который устанавливает позицию
и размеры вложенного элемента. Значение пло умолчанию - (0,0,AutoSize,AutoSize)
LayoutFlags: представляет объект типа AbsoluteLayoutFlags, который указывает,
будут ли размеры и позиция вложенного элемента определяться пропорционально. Значение по умолчанию AbsoluteLayoutFlags.None
.
Непосредственно для добавления элементов у класса AbsoluteLayout мы можем использовать метод Add(), который в качестве параметра принимает добавляемый элемент.
Для создания абсолютного позиционирования необходимо определить прямоугольную область, которую будет занимать элемент. Для этого используется структура Rect, которая представляет прямоугольник:
int x = 10; // позиция координаты X на странице int y = 10; // позиция координаты Y на странице int width = 100; // ширина блока элемента int height = 80; // высота блока элемента Rect rect = new Rect(x, y, width, height);
Для установки размеров и позиции элементов у класса AbsoluteLayout применяется метод SetLayoutBounds()
public void SetLayoutBounds(IView view, Rect bounds);
Первый параметр метода - добавляемый элемент, а второй - прямоугольная область Rect, которую элемент будет занимать. Например, добавим пару элементов:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { AbsoluteLayout absoluteLayout = new AbsoluteLayout(); // определяем элементы BoxView boxView = new BoxView { Color = Colors.LightBlue }; Label label = new Label { Text = ".NET MAUI on METANIT.COM", FontSize = 20 }; // добавляем элементы в AbsoluteLayout absoluteLayout.Add(boxView); absoluteLayout.Add(label); // определяем для элементов расположение и размеры absoluteLayout.SetLayoutBounds( boxView, new Rect(30, 70, 340, 100) ); absoluteLayout.SetLayoutBounds( label, new Rect(50, 100, 300, 40) ); Content = absoluteLayout; } } }
В данном случае метка label накладывается на элемент BoxView, который представляет прямоугольник, заполненный цветом. Таким образом, AbsoluteLayout позволяет нам осуществлять перекрытие одних элементов другими.
Для задания автоматических ширины и длины мы можем использовать значение AbsoluteLayout.AutoSize:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { AbsoluteLayout absoluteLayout = new AbsoluteLayout(); // определяем элементы BoxView boxView = new BoxView { Color = Colors.LightBlue }; Label label = new Label { Text = ".NET MAUI on METANIT.COM", FontSize = 20 }; // добавляем элементы в AbsoluteLayout absoluteLayout.Add(boxView); absoluteLayout.Add(label); // определяем для элементов расположение absoluteLayout.SetLayoutBounds( boxView, new Rect(30, 70, 340, 100) ); absoluteLayout.SetLayoutBounds( label, new Rect(50, 100, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize) ); Content = absoluteLayout; } } }
Здесь для метки применяются автоматические ширина и высота. Поэтому для нее устанавливается только точка верхнего левого угла занимаемой области, а высота и ширина этой области расчитываются автоматически исходя из ширины и высоты элемента.
Для создания абсолютного позиционирования в XAML у элемента устанавливается свойство AbsoluteLayout.LayoutBounds, которое фактически представляет прямоугольную область:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage"> <AbsoluteLayout Margin="20"> <BoxView Color="LightPink" AbsoluteLayout.LayoutBounds="30, 70, 340, 100" /> <Label Text=".NET MAUI on METANIT.COM" FontSize="20" AbsoluteLayout.LayoutBounds="50, 100" /> </AbsoluteLayout> </ContentPage>
В случае с меткой нам неизвестная точная ширина и длина, поэтому для нее не указаны конкретные размеры - они будут устанавливаться автоматически. Либо мы можем явным образом указать,
что размеры автоматические с помощью значения AutoSize
.
<Label Text=".NET MAUI on METANIT.COM" FontSize="20" AbsoluteLayout.LayoutBounds="50, 100, AutoSize, AutoSize" />
Часто бывает сложно подобрать точные размеры или позицию для элементов. И в этом случае мы можем установить пропорциональные размеры и позиции. Для этого используется перечисление AbsoluteLayoutFlags, которое может принимать следующие значения:
None
: все значения интерпретируются как абсолютные
All
: все значения интерпретируются как пропорциональные
WidthProportional
: пропорциональной считается только ширина прямоугольной области элемента, а все остальные значения рассматриваются как абсолютные
HeightProportional
: пропорциональной считается только высота прямоугольной обласи элемента, а все остальные значения рассматриваются как абсолютные
XProportional
: пропорциональной считается только координата X элемента, а все остальные значения рассматриваются как абсолютные
YProportional
: пропорциональной считается только координата Y элемента, а все остальные значения рассматриваются как абсолютные
PositionProportional
: пропорциональными считаются только координаты X и Y позиции элемента
SizeProportional
: пропорциональными считаются только ширина и высота прямоугольной области элемента
При использовании пропорциональных значений все эти значения рассчитываются в диапазоне от 0.0 до 1.0. Например, если мы хотим, чтобы элемент занимал половину ширины контейнера и четверть высоты, то для ширины нужно установить значение 0.5, а для высоты - 0.25.
Таким образом, ширина элемента будет вычисляться по следющей формуле:
ширина_элемента = пропорциональная_ширина_элемента * ширина_контейнера
Аналогично с координатами. Например, координата X будет вычисляться по следующей формуле:
координатаХ_элемента = (ширина_контейнера - ширина_элемента) * пропорциональное_значениеХ_элемента
Например, пусть контейнер AbsoluteLayout имеет ширину в 400 единиц, и пусть вложенный элемент имеет ширину в 100 единиц и пропорциональное значение координаты X равное 0.2. Тогда реальная позиция координаты Х будет равна (400-100) * 0.2 = 60 пикселей от левого края контейнера AbsoluteLayout.
Для установки нужного флага для определенного элемента используется статический метод AbsoluteLayout.SetLayoutFlags().
public void SetLayoutFlags(IView view, AbsoluteLayoutFlags flags);
Первый параметр указывает на элемент, для которого устанавливаются флаг AbsoluteLayoutFlags из второго параметра.
Используем пропорциональные значения:
using Microsoft.Maui.Layouts; namespace HelloApp { class StartPage : ContentPage { public StartPage() { AbsoluteLayout absoluteLayout = new AbsoluteLayout(); BoxView redBox = new BoxView { BackgroundColor = Colors.Red }; BoxView greenBox = new BoxView { BackgroundColor = Colors.Green }; BoxView blueBox = new BoxView { BackgroundColor = Colors.Blue }; AbsoluteLayout.SetLayoutBounds(redBox, new Rect(0.1, 0.2, 50, 80)); // устанавливаем пропорциональные координаты AbsoluteLayout.SetLayoutFlags(redBox, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds(greenBox, new Rect(1, 0.2, 50, 80)); AbsoluteLayout.SetLayoutFlags(greenBox, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds(blueBox, new Rect(0.4, 0.8, 0.2, 0.2)); // пропорциональные координаты и размеры AbsoluteLayout.SetLayoutFlags(blueBox, AbsoluteLayoutFlags.All); absoluteLayout.Children.Add(redBox); absoluteLayout.Children.Add(greenBox); absoluteLayout.Children.Add(blueBox); Content = absoluteLayout; } } }
Аналогичный код в XAML будет выглядеть следующим образом:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage"> <AbsoluteLayout> <BoxView Color="Red" AbsoluteLayout.LayoutBounds=".1, .2, 50, 80" AbsoluteLayout.LayoutFlags="PositionProportional" /> <BoxView Color="Green" AbsoluteLayout.LayoutBounds="1, .2, 50, 80" AbsoluteLayout.LayoutFlags="PositionProportional" /> <BoxView Color="Blue" AbsoluteLayout.LayoutBounds=".4, .8, .2, .2" AbsoluteLayout.LayoutFlags="All" /> </AbsoluteLayout> </ContentPage>