RelativeLayout

Последнее обновление: 09.01.2021

Контейнер RelativeLayout задает относительное позиционирование вложенных элементов относительно сторон контейнера или относительно других элементов.

RelativeLayout в XAML

Позиционирование и размеры элементов внутри RelativeLayout определяются с помощью ограничений, которые в XAML представляют следующие прикрепляемые свойства:

  • RelativeLayout.XConstraint: задает расположение относительно оси X

  • RelativeLayout.YConstraint: задает расположение относительно оси Y

  • RelativeLayout.HeightConstraint: задает высоту элемента

  • RelativeLayout.WidthConstraint: задает ширину элемента

RelativeLayout.HeightConstraint и RelativeLayout.WidthConstraint устанавливаются с помощью числоого значения. А RelativeLayout.XConstraint и RelativeLayout.YConstraint задаются с помощью расширения разметки ConstraintExpression, которое включает следующую информацию:

  • Type: тип ограничения, который указывает, применяется ограничение относительно контейнера или других элементов

  • Property: свойство, на основании которого устанавливается ограничение

  • Factor: множитель, на который умножается длина между границами контейнера (0 и 1 - крайние значения)

  • Constant: смещение относительно контейнера или относительно элемента (в зависимости от значения свойства Type)

  • ElementName: название элемента, к которому применяется ограничение

Например, позиционирование элемента BoxView в RelativeLayout в XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <RelativeLayout>
        <BoxView WidthRequest="100" HeightRequest="100" Color="Blue" 
            RelativeLayout.XConstraint= "{ConstraintExpression 
                Type=RelativeToParent, 
                Property=Width,
                Factor=0.5, 
                Constant=-50}"  
        />
    </RelativeLayout>
</ContentPage>

В данном случае у BoxView устанавливается ограничение RelativeLayout.XConstraint, которое задает смещение относительно оси X, то есть остступ слева. По умолчанию он равен. В данном случае Type=RelativeToParent указывает, что смещение будет идти относительно контейнера. Property=Width говорит, что при вычислении значения используется ширина (контейнера).

Выражение Factor=0.5 указывает, что для вычисления значения надо умножить предельное значение свойства из Property на 0.5, то есть ширина контейнера умножается на 0.5.

Выражение Constant=-50 добавляет дополнительное смещение в виде 50 назад. Это смещение может как положительным, так и отрицательным.

То есть в итоге мы получаем x = Width * 0.5 - 50. Фактически в данном случае BoxView центрируется по ширине.

RelativeLayout in Xamarin

Подобным образом добавим второе ограничение RelativeLayout.YConstraint:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <RelativeLayout>
        <BoxView WidthRequest="100" HeightRequest="100" Color="Blue" 
            RelativeLayout.XConstraint= "{ConstraintExpression Type=RelativeToParent, 
                Property=Width, Factor=0.5, Constant=-50}" 
           RelativeLayout.YConstraint= "{ConstraintExpression Type=RelativeToParent,
                Property=Height, Factor=0.5, Constant=-50}"
        />
    </RelativeLayout>
</ContentPage>
RelativeLayout ConstraintExpression in Xamarin Forms

При установке размеров элементов в RelativeLayout в XAML мы можем использовать две стратегии:

  • Установить значения через свойства HeightRequest и WidthRequest у элементов

  • Установить ограничения RelativeLayout.HeightConstraint и RelativeLayout.WidthConstraint

Первая сратегия продемонстрирована на примерах выше, где у BoxView устанавливались атрибуты HeightRequest и WidthRequest. Теперь применим другую стратегию:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <RelativeLayout>
        <BoxView Color="Blue" 
            RelativeLayout.XConstraint= "{ConstraintExpression Type=RelativeToParent, 
                Property=Width, Factor=0.5, Constant=-50}" 
           RelativeLayout.YConstraint= "{ConstraintExpression Type=RelativeToParent,
                Property=Height, Factor=0.5, Constant=-50}"
           RelativeLayout.WidthConstraint="100" RelativeLayout.HeightConstraint="100"
        />
    </RelativeLayout>
</ContentPage>

RelativeLayout в C#

Перепишим предыдущий пример в C#:

class MainPage : ContentPage
{
    public MainPage()
    {
        RelativeLayout relativeLayout = new RelativeLayout();

		BoxView blueBox = new BoxView { BackgroundColor = Color.Blue };

		relativeLayout.Children.Add(blueBox,
			Constraint.RelativeToParent((parent) =>
			{
				return parent.Width * 0.5 - 50;  // установка координаты X
            }),
			Constraint.RelativeToParent((parent) =>
			{
				return parent.Height * 0.5 - 50; // установка координаты Y
            }),
			Constraint.Constant(100), // установка ширины
			Constraint.Constant(100)  // установка высоты
		);
		Content = relativeLayout;
    }
}

Метод Children.Add() у RelativeLayout имеет ряд перегрузок, позволяющих определить относительные координаты элемента. В качестве первого параметра передается сам элемент. Остальные параметры не являются обязательными, и их набор можно варьировать. Он последовательно принимает значения для x-координаты верхнего левого угла элемента, y-координаты, ширины и высоты.

Второй и третий параметры метода устанавливают координаты X и Y. Здесь нам надо передать объект Constraint, который будет возвращать какое-нибудь значение. Это значение может быть константным и задаваться с помощью метода Constraint.Constant. Либо это может быть значение, вычисляемое динамически, например, относительно параметров контейнера.

Для позиционирования относительно контейнера значения устанавливаются с помощью метода Constraint.RelativeToParent(), который в качестве параметра использует делегат. В лямбда-выражение, которое применяется за место делегата, передается значение parent, содержащее ссылку на родительский контейнер, то есть на RalativeLayout. Через свойства parent.Width и parent.Height можо получить ширину и высоту контейнера в процессе выполнения, а оператор return возвращает непосредственное значение.

Для определения размеров элементов в RelativeLayout в коде C# мы можем использовать одну из трех опций:

  • Установить значения через свойства HeightRequest и WidthRequest у элементов

  • Установить константное значение через метод Constraint.Constant()

  • Установить динамическое значение через метод Constraint.RelativeToParent, который также как и в случае с координатами может принимать во внимание параметры контейнера

Позиционирование относительно другого элемента

При позиционировании относительно другого элемента необходимо задать параметр ElementName:

Позиционирование относительно элемента в XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <RelativeLayout>
        <Label x:Name="lbl" Text="RelativeLayout"
             RelativeLayout.XConstraint = "{ConstraintExpression Type=RelativeToParent,
             Property=Width, Factor=0.5, Constant=-50}"
              RelativeLayout.YConstraint = "{ConstraintExpression Type=RelativeToParent, 
              Property=Height, Factor=0.5, Constant=-150}"
        />
        <BoxView Color="Blue"
             RelativeLayout.XConstraint = "{ConstraintExpression Type=RelativeToView, ElementName=lbl,
             Property=X, Factor=1, Constant=-30}"
              RelativeLayout.YConstraint = "{ConstraintExpression Type=RelativeToView, ElementName=lbl, 
              Property=Y, Factor=1, Constant=30}"
            RelativeLayout.WidthConstraint = "150" RelativeLayout.HeightConstraint = "100"/>
    </RelativeLayout>
</ContentPage>

В данном случае позиционирование элемента Label устанавливается относительно контейнера RelativeLayout. А элемент BoxView устанавливается относительно элемента Label. В данном случае BoxView.X = lbl.X * 1 - 30. Аналогично вычисляется положение по оси Y.

Позиционирование относительно элемента в Xamarin Forms

Для позиционирования элемента в коде C# относительно других элементов мы могли бы использовать метод Constraint.RelativeToView() вместо Constraint.RelativeToParent(). Например, перепишем предыдущий пример в C#:

using Xamarin.Forms;

namespace HelloApp
{
    public partial class MainPage : ContentPage
    {

        public MainPage()
        {
            //InitializeComponent();
            RelativeLayout relativeLayout = new RelativeLayout();

            Label label = new Label { Text = "RelativeLayout"};
            BoxView blueBox = new BoxView { BackgroundColor = Color.Blue };

            relativeLayout.Children.Add(label,
                Constraint.RelativeToParent((parent) =>
                {
                    return parent.Width * 0.5 - 50;    // установка координаты X
                }),
                Constraint.RelativeToParent((parent) =>
                {
                    return parent.Height * 0.5 - 150;   // установка координаты Y
                })
            );

            relativeLayout.Children.Add(blueBox,
                Constraint.RelativeToView(label, (parent, view) =>
                {
                    return label.X - 30;    // установка координаты X
                }),
                Constraint.RelativeToView(label, (parent, view) =>
                {
                    return label.Y + 30;    // установка координаты Y
                }),
                Constraint.Constant(150), // установка ширины
                Constraint.Constant(100) // установка высоты
            );

            Content = relativeLayout;
        }
    }
}

В метод Constraint.RelativeToView() передается элемент, относительно которого задается позиционирование (то есть label), и далее передается делегат, входные параметры которого - контейнер и элемент.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850