Сводная информация о Главе 14. Абсолютный макет
Примечание.
Эта книга была опубликована весной 2016 года и с тех пор не обновлялась. Многое в этой книге остается ценным, но некоторые материалы устарели, а некоторые разделы перестали быть полностью верными или полными.
Как и StackLayout
, AbsoluteLayout
является производным от Layout<View>
и наследует свойство Children
. AbsoluteLayout
реализует систему макета, в которой программисту нужно указывать позиции дочерних элементов и их размер (необязательно). Эти позиции определяются по координатам левого верхнего угла дочернего элемента относительно левого верхнего угла AbsoluteLayout
, выраженным в не зависящих от устройства единицах измерения. AbsoluteLayout
также реализует функции пропорционального размещения и изменения размера.
AbsoluteLayout
следует рассматривать как специализированную систему макета, которая используется только в том случае, когда программисту важно строго определять размер дочерних элементов (например, элементов BoxView
) или когда размер элемента не влияет на расположение других дочерних элементов. Свойства HorizontalOptions
и VerticalOptions
не влияют на дочерние элементы AbsoluteLayout
.
В этой главе также представлена важная концепция присоединенных привязываемых свойств, которые позволяют присоединять свойства, определенные в одном классе (в нашем примере это AbsoluteLayout
) к другому классу (дочернему элементу AbsoluteLayout
).
Код для AbsoluteLayout
Вы можете добавить дочерний элемент в коллекцию Children
элемента AbsoluteLayout
с помощью стандартного метода Add
, но AbsoluteLayout
предоставляет еще и расширенный метод Add
, который позволяет указать Rectangle
. Еще один метод Add
требует только Point
, то есть дочерний элемент неограничен и самостоятельно задает свои размеры.
Можно создать Rectangle
значение с конструктором, требующим четырех значений — первые два, указывающие положение левого верхнего угла дочернего элемента относительно родительского элемента, а второй — размер дочернего элемента. Также можно использовать конструктор, который принимает Point
и значение Size
.
Эти методы Add
демонстрируются в примере AbsoluteDemo, который позиционирует элементы BoxView
с помощью значений Rectangle
и элемент Label
по одному значению Point
.
В примере ChessboardFixed для создания шаблона шахматной доски используются 32 элемента BoxView
. Программа присваивает элементам BoxView
жестко запрограммированный размер обеих сторон 35 единиц. Для AbsoluteLayout
параметрам HorizontalOptions
и VerticalOptions
присвоено значение LayoutOptions.Center
, в результате чего общий размер AbsoluteLayout
соответствует квадрату со стороной 280 единиц.
Присоединенные привязываемые свойства
Вы можете также задать позицию и (необязательно) размер дочернего элемента AbsoluteLayout
после добавления его в коллекцию Children
, используя статический метод AbsoluteLayout.SetLayoutBounds
. Первым аргументом он принимает дочерний элемент, а вторым — объект Rectangle
. Можно указать, что дочерние размеры сами по горизонтали и (или) по вертикали задают ширину и высоту AbsoluteLayout.AutoSize
константы.
Пример ChessboardDynamic размещает AbsoluteLayout
в ContentView
с обработчиком SizeChanged
для вызова AbsoluteLayout.SetLayoutBounds
из всех дочерних элементов, чтобы максимально увеличить их размер.
Присоединенное привязываемое свойство, определенное в AbsoluteLayout
, является статическим полем только для чтения с типом BindableProperty
и именем AbsoluteLayout.LayoutBoundsProperty
. Статический метод AbsoluteLayout.SetLayoutBounds
реализуется путем вызова SetValue
из дочернего элемента с помощью AbsoluteLayout.LayoutBoundsProperty
. Этот дочерний элемент содержит словарь, в котором хранятся присоединенное привязываемой свойство и его значение. На этапе создания макета AbsoluteLayout
может получить это значение, вызвав AbsoluteLayout.GetLayoutBounds
, который реализуется вызовом GetValue
.
Пропорциональный размер и размещение
AbsoluteLayout
реализует функцию пропорционального размера и размещения. Этот класс определяет второе присоединенное привязываемой свойство LayoutFlagsProperty
с соответствующими статическими методами AbsoluteLayout.SetLayoutFlags
и AbsoluteLayout.GetLayoutFlags
.
Аргумент AbsoluteLayout.SetLayoutFlags
и возвращаемое значение AbsoluteLayout.GetLayoutFlags
имеют тип AbsoluteLayoutFlags
, то есть перечисление со следующими элементами:
None
(равно значению 0);XProportional
(1);YProportional
(2);PositionProportional
(3);WidthProportional
(4);HeightProportional
(8);SizeProportional
(12);All
(\xFFFFFFFF).
Их можно объединять с помощью оператора "побитового ИЛИ" из C#.
При установке этих флагов некоторые свойства структуры связывания макета Rectangle
, которые применяются для выбора положения и размера дочернего элемента, рассматриваются как пропорциональные.
Если задан флаг WidthProportional
, значение 1 для параметра Width
означает, что ширина дочернего элемента совпадает с шириной AbsoluteLayout
. Такой же подход используется для высоты.
При пропорциональном размещении учитывается размер элементов. Если задан флаг XProportional
, свойство X
структуры макета Rectangle
вычисляется как пропорциональное. Значение 0 означает, что левый край дочернего элемента размещается по левому краю AbsoluteLayout
, но положение 1 означает, что правый край дочернего элемента размещается по правому краю AbsoluteLayout
, а не за правым краем AbsoluteLayout
, как можно было бы ожидать. Значение 0,5 для свойства X
размещает дочерний элемент в центре AbsoluteLayout
по горизонтальной оси.
Пример ChessboardProportional демонстрирует применение функции пропорционального размера и размещения.
Использование пропорциональных координат
Иногда бывает удобно использовать пропорциональное размещение не так, как оно реализовано в AbsoluteLayout
. Вы можете предпочесть пропорциональные координаты, при использовании которых значение 1 для свойства X
размещает левый (а не правый) край дочернего элемента по правому краю AbsoluteLayout
.
Эту альтернативную схему размещения можно назвать "дробными дочерними координатами". Вы можете преобразовать из дробных дочерних координат в границы макета, необходимые для AbsoluteLayout
использования следующих формул:
layoutBounds.X = (fractionalChildCoordinate.X / (1 - layoutBounds.Width))
layoutBounds.Y = (fractionalChildCoordinate.Y / (1 - layoutBounds.Height))
Этот подход демонстрируется в примере ProportionalCoordinateCalc.
AbsoluteLayout и XAML
Вы можете применить AbsoluteLayout
в XAML и настроить присоединенные привязываемые свойства дочерних элементов AbsoluteLayout
с помощью значений атрибутов AbsoluteLayout.LayoutBounds
и AbsoluteLayout.LayoutFlags
. Этот подход применяется в примерах AbsoluteXamlDemo и ChessboardXaml. Вторая из этих программ содержит 32 элемента BoxView
, но с помощью неявного Style
со свойством AbsoluteLayout.LayoutFlags
обходится минимальным количеством разметки.
В XAML атрибут, состоящий из имени класса, символа точки и имени свойства всегда является присоединенным привязываемым свойством.
Наложения
Вы можете с помощью AbsoluteLayout
создать наложение, которое перекрывает страницу другими элементами управления, например для защиты от вмешательства пользователя в работу основных элементов управления на этой страницы.
Пример SimpleOverlay демонстрирует эту методику и ProgressBar
, с помощью которой обозначает ход выполнения задачи в программе.
Немного развлечений
Пример DotMatrixClock отображает текущее время на модели матричного дисплея размером 5x7 точек. Каждая точка представляет собой BoxView
(в общей сложности их 228), которому присваивается размер и положение на AbsoluteLayout
.
Программа BouncingText перемещает по экрану два объекта Label
, моделируя отражение от горизонтальных и вертикальных границ экрана.