Выбор макета Xamarin.Forms

Xamarin.Forms Классы макетов позволяют упорядочивать и группировать элементы управления пользовательского интерфейса в приложении. При выборе класса макета требуется знание того, как макет помещает дочерние элементы и как макет размеров его дочерних элементов. Кроме того, может потребоваться вложить макеты, чтобы создать нужный макет.

На следующем рисунке показаны типичные макеты, которые можно достичь с помощью основных Xamarin.Forms классов макетов:

Основные классы макета в Xamarin.Forms

StackLayout

Элемент StackLayout упорядочивает элементы в одномерном стеке по горизонтали или по вертикали. Свойство Orientation указывает направление элементов, а ориентация по умолчанию — Vertical. StackLayout обычно используется для упорядочивания подраздела пользовательского интерфейса на странице.

В следующем XAML показано, как создать вертикальную, StackLayout содержащую три Label объекта:

<StackLayout Margin="20,35,20,25">
    <Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
    <Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
    <Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>

StackLayoutЕсли размер элемента не задан явным образом, он расширяется для заполнения доступной ширины или высоты, если Orientation для свойства задано Horizontalзначение .

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

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name:" />
            <Entry Placeholder="Enter your name" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Age:" />
            <Entry Placeholder="Enter your age" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Occupation:" />
            <Entry Placeholder="Enter your occupation" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Address:" />
            <Entry Placeholder="Enter your address" />
        </StackLayout>
    </StackLayout>
</ContentPage>

Такой метод неэффективен, так как выполняются ненужные вычисления макета. Вместо этого нужное макет можно лучше достичь с помощью .Grid>.

Совет

При использовании StackLayoutубедитесь, что для одного дочернего элемента задано значение LayoutOptions.Expands. В этом случае указанный дочерний элемент будет занимать максимальное пространство, предоставляемое ему макетом StackLayout. Выполнять эти вычисления несколько раз слишком затратно.

Дополнительные сведения см. в статье Xamarin.Forms StackLayout.

Сетка

Используется Grid для отображения элементов в строках и столбцах, которые могут иметь пропорциональные или абсолютные размеры. Строки и столбцы сетки указываются со свойствами RowDefinitions и ColumnDefinitions свойствами.

Чтобы разместить элементы в определенных Grid ячейках, используйте Grid.Column свойства и Grid.Row присоединенные свойства. Чтобы сделать элементы диапазоном между несколькими строками и столбцами, используйте Grid.RowSpan свойства и Grid.ColumnSpan присоединенные свойства.

Примечание.

Grid Макет не следует путать с таблицами и не предназначен для представления табличных данных. В отличие от HTML-таблиц, Grid он предназначен для размещения содержимого. Для отображения табличных данных рекомендуется использовать ListView, CollectionView или TableView.

В следующем XAML показано, как создать с Grid двумя строками и двумя столбцами:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>    
    <Label Text="Column 0, Row 0"
           WidthRequest="200" />
    <Label Grid.Column="1"
           Text="Column 1, Row 0" />
    <Label Grid.Row="1"
           Text="Column 0, Row 1" />
    <Label Grid.Column="1"
           Grid.Row="1"
           Text="Column 1, Row 1" />
</Grid>

В этом примере размер работает следующим образом:

  • Каждая строка имеет явную высоту 50 независимых от устройств единиц.
  • Для первого столбца задана Autoширина первого столбца, поэтому она должна быть максимально широкой, как это требуется для дочерних элементов. В этом случае это 200 единиц, независимых от устройств, для размещения ширины первой Label.

Пространство можно распределять в столбце или строке с помощью автоматического изменения размера, что позволяет столбцам и строкам соответствовать их содержимому. Это достигается путем задания высоты RowDefinitionили ширины , равнойColumnDefinitionAuto. Пропорциональный размер также можно использовать для распределения доступного пространства между строками и столбцами сетки по взвешанным пропорциям. Это достигается путем задания высоты RowDefinitionили ширины значения ColumnDefinition, которое использует * оператор.

Внимание

Попробуйте убедиться, что для Auto размера задано максимальное количество строк и столбцов. Из-за каждой строки или столбца с автоматическим размером обработчик макета будет выполнять дополнительные вычисления макета. Если возможно, используйте строки и столбцы фиксированного размера. Кроме того, задайте для строк и столбцов пропорциональный объем пространства со GridUnitType.Star значением перечисления.

Дополнительные сведения см. в разделе Xamarin.Forms "Сетка".

FlexLayout

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

В следующем XAML показано, как создать FlexLayout представление, отображающее его представления в одном столбце:

<FlexLayout Direction="Column"
            AlignItems="Center"
            JustifyContent="SpaceEvenly">
    <Label Text="FlexLayout in Action" />
    <Button Text="Button" />
    <Label Text="Another Label" />
</FlexLayout>

В этом примере макет работает следующим образом:

  • Для Direction свойства задано значение Column, которое приводит к упорядочению дочерних FlexLayout элементов в одном столбце элементов.
  • Для AlignItems свойства задано значение Center, которое приводит к горизонтальному центру каждого элемента.
  • Для JustifyContent свойства задано SpaceEvenlyзначение , которое выделяет все левое вертикальное пространство между всеми элементами и выше первого элемента и ниже последнего элемента.

Дополнительные сведения см. в разделе Xamarin.Forms FlexLayout.

RelativeLayout

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

RelativeLayoutВ пределах позиции и размеры указываются в виде ограничений. Ограничения имеют Factor и Constant свойства, которые можно использовать для определения позиций и размеров в виде нескольких (или дробей) свойств других объектов, а также константы. Кроме того, константы могут быть отрицательными.

Примечание.

Поддерживает RelativeLayout размещение элементов за пределами собственных границ.

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

<RelativeLayout>
    <BoxView Color="Blue"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView Color="Red"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.85}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView x:Name="pole"
             Color="Gray"
             WidthRequest="15"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.75}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.45}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.25}" />
    <BoxView Color="Green"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.10, Constant=10}"
             RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.2, Constant=20}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=X, Constant=15}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=Y, Constant=0}" />
</RelativeLayout>

В этом примере макет работает следующим образом:

  • BoxView Синий цвет имеет явный размер 50x50 независимых от устройств единиц. Он помещается в левый верхний угол макета, который является позицией по умолчанию.
  • Красный BoxView цвет получает явный размер 50x50 независимых от устройств единиц. Он помещается в правый верхний угол макета.
  • BoxView Серый цвет имеет явную ширину 15 независимых от устройств единиц, и ее высота составляет 75 % от высоты родительского элемента.
  • BoxView Зеленый цвет не указан явным размером. Его положение устанавливается относительно именованного BoxView pole.

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

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

Дополнительные сведения см. в разделе Xamarin.Forms RelativeLayout.

AbsoluteLayout

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

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

Внимание

Свойства HorizontalOptions и VerticalOptions не влияют на дочерние элементы AbsoluteLayout.

AbsoluteLayoutВ пределах присоединенного AbsoluteLayout.LayoutBounds свойства используется для указания горизонтальной позиции, вертикальной позиции, ширины и высоты элемента. Кроме того, присоединенное AbsoluteLayout.LayoutFlags свойство указывает, как будут интерпретироваться границы макета.

В следующем коде XAML показано, как упорядочить элементы в следующем коде AbsoluteLayout:

<AbsoluteLayout Margin="40">
    <BoxView Color="Red"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="30" />
    <BoxView Color="Green"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="60" />
    <BoxView Color="Blue"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" />
</AbsoluteLayout>

В этом примере макет работает следующим образом:

  • Каждый из них BoxView имеет явный размер 100x100 и отображается в той же позиции по горизонтали.
  • Красный BoxView поворачивается 30 градусов, и зеленый BoxView поворачивается 60 градусов.
  • На каждом BoxViewприсоединенном AbsoluteLayout.LayoutFlags свойстве задано PositionProportionalзначение , указывающее, что позиция пропорциональна оставшемсяу пространству после ширины и высоты.

Внимание

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

Дополнительные сведения см. в разделе Xamarin.Forms AbsoluteLayout.

Прозрачность входных данных

Каждый визуальный InputTransparent элемент имеет свойство, используемое для определения того, получает ли элемент входные данные. Значение по умолчанию — falseэто обеспечение того, что элемент получает входные данные.

Если это свойство задано в классе макета, его значение передается дочерним элементам. Поэтому установка InputTransparent свойства true в классе макета приведет ко всем элементам макета, не получающим входных данных.

Производительность макета

Чтобы получить оптимальную производительность макета, следуйте рекомендациям по оптимизации производительности макета.

Кроме того, производительность отрисовки страниц также можно улучшить с помощью сжатия макета, который удаляет указанные макеты из визуального дерева. Дополнительные сведения см. в разделе " Сжатие макета".