Поделиться через


Xamarin.Forms RelativeLayout

Xamarin.Forms RelativeLayout

A RelativeLayout используется для размещения и размера дочерних элементов относительно свойств макета или элементов с одноуровневым элементом. Это позволяет создавать пользовательские интерфейсы, пропорционально масштабируемые по размеру устройства. Кроме того, в отличие от некоторых других классов макетов, можно размещать дочерние элементы таким RelativeLayout образом, чтобы перекрываться.

Класс RelativeLayout определяет следующие свойства:

  • XConstraintConstraintтип , который является присоединенным свойством, которое представляет ограничение на положение X дочернего элемента.
  • YConstraintConstraintтип , который является присоединенным свойством, которое представляет ограничение на положение Y дочернего элемента.
  • WidthConstraintConstraintтип , который представляет собой присоединенное свойство, представляющее ограничение ширины дочернего элемента.
  • HeightConstraintConstraintТип , который является присоединенным свойством, которое представляет ограничение на высоту дочернего элемента.
  • BoundsConstraintТип BoundsConstraint, который является присоединенным свойством, которое представляет ограничение на положение и размер дочернего элемента. Это свойство нельзя легко использовать из XAML.

Эти свойства поддерживаются объектами, что означает, что свойства могут быть целевыми BindableProperty объектами привязки данных и стилем. Дополнительные сведения о присоединенных свойствах см. в разделе Xamarin.Forms "Присоединенные свойства".

Примечание.

Ширину и высоту дочернего элемента RelativeLayout можно также указать с помощью свойств и HeightRequest свойств дочернего WidthRequest элемента, а не WidthConstraint HeightConstraint присоединенных свойств.

Класс RelativeLayout является производным от Layout<T> класса, который определяет Children свойство типа IList<T>. Свойство Children является ContentProperty классом Layout<T> , поэтому не требуется явно задавать из XAML.

Совет

По возможности избегайте использования RelativeLayout. В противном случае ЦП будет испытывать значительно большую нагрузку.

Ограничения

В пределах RelativeLayoutполя положение и размер дочерних элементов указываются в виде ограничений с использованием абсолютных значений или относительных значений. Если ограничения не указаны, дочерний элемент будет расположен в левом верхнем углу макета.

В следующей таблице показано, как указать ограничения в XAML и C#:

XAML C#
Абсолютные значения Абсолютные ограничения задаются путем задания присоединенных RelativeLayout свойств значениям double . Абсолютные ограничения задаются методом Constraint.Constant или с помощью Children.Add перегрузки, требующей аргумента Func<Rectangle> .
Относительные значения Относительные ограничения задаются путем задания RelativeLayout присоединенных свойств Constraint объектам, возвращаемым расширением ConstraintExpression разметки. Относительные ограничения задаются Constraint объектами, возвращаемыми методами Constraint класса.

Дополнительные сведения об указании ограничений с помощью абсолютных значений см. в разделе "Абсолютное положение" и "Изменение размера". Дополнительные сведения об указании ограничений с использованием относительных значений см. в разделе "Относительное положение" и "Изменение размера".

В C#дочерние элементы можно добавлять RelativeLayout в три Add перегрузки. Для первой перегрузки требуется Expression<Func<Rectangle>> указать положение и размер дочернего элемента. Для второй перегрузки требуются необязательные Expression<Func<double>> объекты для xyаргументов , widthи height аргументов. Для третьей перегрузки требуются необязательные Constraint объекты для xyаргументов , widthи height аргументов.

Можно изменить позицию и размер дочернего объекта с RelativeLayout помощью методов SetYConstraintи SetWidthConstraintSetHeightConstraint методов, а SetXConstraintтакже их размера. Первым аргументом каждого из этих методов является дочерний, а второй — Constraint объект. Кроме того, SetBoundsConstraint этот метод также можно использовать для изменения положения и размера дочернего элемента. Первый аргумент этого метода является дочерним, а второй — BoundsConstraint объектом.

Абсолютное расположение и размер

Дочерние RelativeLayout элементы могут размещать и размер с помощью абсолютных значений, указанных в независимых от устройства единицах, которые явно определяют, где дочерние элементы должны размещаться в макете. Это достигается путем добавления дочерних элементов в Children коллекцию и задания XConstraintсвойств , YConstraintWidthConstraintи HeightConstraint присоединенных свойств для каждого дочернего RelativeLayout элемента к абсолютной позиции и (или) значений размера.

Предупреждение

Использование абсолютных значений для размещения и изменения размера дочерних элементов может быть проблематичным, так как разные устройства имеют разные размеры экрана и разрешения. Таким образом, координаты центра экрана на одном устройстве могут быть смещения на других устройствах.

В следующем коде XAML показано, RelativeLayout чьи дочерние элементы расположены с помощью абсолютных значений:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.StylishHeaderDemoPage"
             Title="Stylish header demo">
    <RelativeLayout Margin="20">
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="10"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="0"
                 RelativeLayout.YConstraint="20"
                 RelativeLayout.WidthConstraint="200"
                 RelativeLayout.HeightConstraint="5" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="10"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <BoxView Color="Silver"
                 RelativeLayout.XConstraint="20"
                 RelativeLayout.YConstraint="0"
                 RelativeLayout.WidthConstraint="5"
                 RelativeLayout.HeightConstraint="65" />
        <Label Text="Stylish header"
               FontSize="24"
               RelativeLayout.XConstraint="30"
               RelativeLayout.YConstraint="25" />
    </RelativeLayout>
</ContentPage>

В этом примере позиция каждого BoxView объекта определяется с помощью значений, указанных в XConstraint свойствах и YConstraint присоединенных свойствах. Размер каждого BoxView определяется с помощью значений, указанных в WidthConstraint свойствах и HeightConstraint присоединенных свойствах. Позиция Label объекта также определяется с помощью значений, указанных в свойствах и YConstraint присоединенных XConstraint свойствах. Однако для значения размера не указаны Label, поэтому он не ограничен и сам размер. Во всех случаях абсолютные значения представляют независимые от устройства единицы.

На следующих снимках экрана показан получившийся макет:

Дочерние объекты, помещенные в RelativeLayout с помощью абсолютных значений

Ниже приведен эквивалентный код на C#:

public class StylishHeaderDemoPageCS : ContentPage
{
    public StylishHeaderDemoPageCS()
    {
        RelativeLayout relativeLayout = new RelativeLayout
        {
            Margin = new Thickness(20)
        };

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 10, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(0, 20, 200, 5));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(10, 0, 5, 65));

        relativeLayout.Children.Add(new BoxView
        {
            Color = Color.Silver
        }, () => new Rectangle(20, 0, 5, 65));

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

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

В этом примере BoxView объекты добавляются в RelativeLayout перегрузку Add , требующую Expression<Func<Rectangle>> указания положения и размера каждого дочернего элемента. Позиция определяется с помощью перегрузкиLabel, требующей необязательных Constraint объектов, в этом случае создается методомConstraint.Constant.Add

Примечание.

Объект, RelativeLayout использующий абсолютные значения, может размещать дочерние элементы и размеры, чтобы они не соответствовали границам макета.

Относительное расположение и изменение размера

Дочерние RelativeLayout элементы могут размещать и размер с помощью значений, которые относятся к свойствам макета или элементов-братьев. Это достигается путем добавления дочерних элементов в Children коллекцию и задания XConstraintсвойств , YConstraintWidthConstraintи HeightConstraint присоединенных свойств для каждого дочернего RelativeLayout элемента к относительным значениям с помощью Constraint объектов.

Ограничения могут быть константой, относительно родительского или относительно одноуровневого элемента. Тип ограничения представлен ConstraintType перечислением, который определяет следующие элементы:

  • RelativeToParent, указывающий ограничение, относительно родительского элемента.
  • RelativeToView— это ограничение относительно представления (или одноуровневого элемента).
  • Constant, указывающий на константное ограничение.

Расширение разметки ограничения

В XAML Constraint объект можно создать с помощью расширения разметки ConstraintExpression . Это расширение разметки обычно используется для связи позиции и размера дочернего элемента внутри RelativeLayout родительского элемента или с одноуровневой связью.

Класс ConstraintExpression определяет следующие свойства:

  • Constantdoubleтип, представляющий значение константы ограничения.
  • ElementNameтип string, представляющий имя исходного элемента, для которого вычисляется ограничение.
  • Factorтип double, представляющий фактор, с помощью которого масштабируется ограниченное измерение относительно исходного элемента. Это свойство по умолчанию — 1.
  • PropertyТип string, представляющий имя свойства исходного элемента, используемого в вычислении ограничения.
  • TypeConstraintTypeтип, представляющий тип ограничения.

Дополнительные сведения о расширениях разметки Xamarin.Forms см. в статье Расширения разметки XAML.

Следующий КОД XAML показывает дочерние RelativeLayout элементы, которые ограничены расширением ConstraintExpression разметки:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RelativeLayoutDemos.Views.RelativePositioningAndSizingDemoPage"
             Title="RelativeLayout demo">
    <RelativeLayout>
        <BoxView Color="Red"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Green"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}" />
        <BoxView Color="Blue"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />
        <BoxView Color="Yellow"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Constant=-40}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-40}" />

        <!-- Centered and 1/3 width and height of parent -->
        <BoxView x:Name="oneThird"
                 Color="Silver"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.33}" />

        <!-- 1/3 width and height of previous -->
        <BoxView Color="Black"
                 RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=X}"
                 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Y}"
                 RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Width, Factor=0.33}"
                 RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=oneThird, Property=Height, Factor=0.33}" />
    </RelativeLayout>
</ContentPage>

В этом примере позиция каждого BoxView объекта определяется путем задания XConstraint и YConstraint присоединенных свойств. Первый BoxView имеет свои XConstraint и YConstraint присоединенные свойства имеют константы, которые являются абсолютными значениями. Остальные BoxView объекты имеют свои позиции, используя по крайней мере одно относительное значение. Например, желтый BoxView объект задает XConstraint присоединенное свойство ширине родительского объекта (минус RelativeLayout40). Аналогичным образом это BoxView задает YConstraint присоединенное свойство на высоту родительского минус 40. Это гарантирует, что желтый цвет BoxView отображается в правом нижнем углу экрана.

Примечание.

BoxView Объекты, которые не указывают размер, автоматически размером до 40x40 по Xamarin.Forms.

Серебряный BoxView именованный oneThird расположен централизованно относительно родительского элемента. Он также имеет размер относительно родительского элемента, что составляет треть от его ширины и высоты. Это достигается путем установки XConstraint и WidthConstraint присоединенных свойств к ширине родительского элемента (т RelativeLayout. е.), умноженного на 0,33. Аналогичным образом YConstraint свойства и HeightConstraint присоединенные свойства имеют высоту родительского объекта, умноженную на 0,33.

Черный BoxView расположен и размер относительно oneThird BoxView. Это достигается путем задания его XConstraint и присоединенных свойств к X значениям и YConstraint Y значениям, соответственно, элемента с братом. Аналогичным образом его размер равен одной трети ширины и высоты его элемента-брата. Это достигается путем задания свойств WidthConstraint и HeightConstraint присоединенных свойств Width к и Height значениям элемента-брата соответственно, которые затем умножаются на 0,33.

На следующем снимке экрана показан получившийся макет:

Дочерние объекты, помещенные в RelativeLayout с использованием относительных значений

Объекты ограничения

Класс Constraint определяет следующие общедоступные статические методы, возвращающие Constraint объекты:

  • Constant, который ограничивает дочерний объект размером, указанным с параметром double.
  • FromExpression, который ограничивает ребенка с помощью лямбда-выражения.
  • RelativeToParent, который ограничивает дочерний объект относительно размера родительского элемента.
  • RelativeToView, который ограничивает дочерний объект относительно размера представления.

Кроме того, BoundsConstraint класс определяет один метод, который возвращает BoundsConstraint значение, FromExpressionкоторое ограничивает положение и размер Expression<Func<Rectangle>>дочернего объекта. Этот метод можно использовать для задания присоединенного BoundsConstraint свойства.

В следующем коде C# показано RelativeLayout , чьи дочерние элементы ограничены объектами Constraint :

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

        // Four BoxView's
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Red },
            Constraint.Constant(0),
            Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Green },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }), Constraint.Constant(0));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Blue },
            Constraint.Constant(0),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        relativeLayout.Children.Add(
            new BoxView { Color = Color.Yellow },
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width - 40;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height - 40;
            }));

        // Centered and 1/3 width and height of parent
        BoxView silverBoxView = new BoxView { Color = Color.Silver };
        relativeLayout.Children.Add(
            silverBoxView,
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Width * 0.33;
            }),
            Constraint.RelativeToParent((parent) =>
            {
                return parent.Height * 0.33;
            }));

        // 1/3 width and height of previous
        relativeLayout.Children.Add(
            new BoxView { Color = Color.Black },
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.X;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Y;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Width * 0.33;
            }),
            Constraint.RelativeToView(silverBoxView, (parent, sibling) =>
            {
                return sibling.Height * 0.33;
            }));

        Title = "RelativeLayout demo";
        Content = relativeLayout;
    }
}

В этом примере дочерние элементы добавляются в перегрузкуAdd, требующую необязательный Constraint объект для xwidthyаргументов , и height аргументов.RelativeLayout

Примечание.

Объект, RelativeLayout использующий относительные значения, может размещать дочерние элементы и размеры, чтобы они не соответствовали границам макета.