Яка різниця між LayoutOptions Xamarin.Form, особливо Fill і Expand?


170

У Xamarin.Forms кожен Viewмає дві властивості HorizontalOptionsі VerticalOptions. Обидва мають тип LayoutOptionsі можуть мати одне з наступних значень:

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill
  • LayoutOptions.StartAndExpand
  • LayoutOptions.CenterAndExpand
  • LayoutOptions.EndAndExpand
  • LayoutOptions.FillAndExpand

Мабуть, він контролює вирівнювання подання для батьківського подання. Але як саме поводиться кожен окремий варіант? І в чому різниця між Fillсуфіксом Expand?

Відповіді:


335

Коротка відповідь

Start, Center, EndІ Fillвизначити вид по узгодженості в її просторі .

Expandвизначає, чи займає вона більше місця, якщо є.

Теорія

Структура LayoutOptionsконтролює дві різні форми поведінки:

  1. Вирівнювання: Як вигляд вирівнюється в батьківському поданні?

    • Start: Для вертикального вирівнювання погляд переміщується вгору. Для горизонтального вирівнювання це, як правило, лівий бік. (Але зауважте, що на пристроях із налаштуваннями мови справа наліво це навпаки, тобто вирівнюється справа.)
    • Center: Вид зосереджений.
    • End: Зазвичай вигляд вирівняний внизу або вправо. (На мовах справа наліво, звичайно, ліворуч вирівнюється.)
    • Fill: Це вирівнювання дещо інше. Вид буде розтягуватися на весь розмір батьківського подання.

    Якщо ж батько не більший, ніж його діти, ви не помітите різниці між цими вирівнюваннями. Вирівнювання має значення лише для батьківських представлень з додатковим місцем.

  2. Розширення: Чи буде елемент займати більше місця, якщо він є?

    • Суфікс Expand: Якщо вигляд батьків перевищує комбінований розмір усіх його дітей, тобто є додатковий простір, то простір пропорційно розподіляється між дочірніми переглядами з цим суфіксом. Ці діти будуть "займати" їх простір, але не обов'язково "заповнювати" його. Ми розглянемо цю поведінку на прикладі нижче.
    • Немає суфікса: Діти без Expandсуфікса не отримають додаткового місця, навіть якщо більше місця.

    Знову ж таки, якщо батьківський вигляд не більший за його дочірніх, суфікс розширення також не має ніякої різниці.

Приклад

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

Додаток містить темно-сірий StackLayoutз вісьмома вкладеними білими кнопками, кожна з яких позначена своїм варіантом вертикального макета. Клацнувши по одній із кнопок, вона призначає свій варіант вертикальної компонування для макета стека. Таким чином ми можемо легко перевірити взаємодію поглядів з батьками, як з різним варіантом компонування.

(Останні кілька рядків коду додають додаткові жовті поля. Ми повернемося до цього через мить.)

public static class App
{
    static readonly StackLayout stackLayout = new StackLayout {
        BackgroundColor = Color.Gray,
        VerticalOptions = LayoutOptions.Start,
        Spacing = 2,
        Padding = 2,
    };

    public static Page GetMainPage()
    {
        AddButton("Start", LayoutOptions.Start);
        AddButton("Center", LayoutOptions.Center);
        AddButton("End", LayoutOptions.End);
        AddButton("Fill", LayoutOptions.Fill);
        AddButton("StartAndExpand", LayoutOptions.StartAndExpand);
        AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand);
        AddButton("EndAndExpand", LayoutOptions.EndAndExpand);
        AddButton("FillAndExpand", LayoutOptions.FillAndExpand);

        return new NavigationPage(new ContentPage {
            Content = stackLayout,
        });
    }

    static void AddButton(string text, LayoutOptions verticalOptions)
    {
        stackLayout.Children.Add(new Button {
            Text = text,
            BackgroundColor = Color.White,
            VerticalOptions = verticalOptions,
            HeightRequest = 20,
            Command = new Command(() => {
                stackLayout.VerticalOptions = verticalOptions;
                (stackLayout.ParentView as Page).Title = "StackLayout: " + text;
            }),
        });
        stackLayout.Children.Add(new BoxView {
            HeightRequest = 1,
            Color = Color.Yellow,
        });
    }
}

На наступних знімках екрана відображається результат при натисканні на кожну з восьми кнопок. Ми робимо такі зауваження:

  • Поки батьків stackLayoutє щільним (не Fillсторінка), варіант вертикального макета кожногоButton є незначним.
  • Варіант вертикального макета має значення лише у тому випадку, якщо stackLayoutбільший (наприклад, за допомогою Fillвирівнювання) та окремі кнопки мають Expandсуфікс.
  • Додатковий простір пропорційно розподіляється між усіма кнопками із Expandсуфіксом. Щоб зрозуміти це, ми додали жовті горизонтальні лінії між кожними двома сусідніми кнопками.
  • Кнопки з більшим простором, ніж потрібна висота, не обов'язково "заповнюють" її. У цьому випадку фактична поведінка контролюється їх вирівнюванням. Наприклад, вони або вирівняні вгорі, по центру або на кнопці місця, або заповнити його повністю.
  • Усі кнопки переходять на всю ширину макета, оскільки ми лише змінюємо VerticalOptions.

Скріншоти

Тут ви знайдете відповідні скріншоти з високою роздільною здатністю.


6
зображення виглядає як [[midfing]], lol просто жартую, що це було дуже корисно
Джой Рекс,

1
@JoyRex: Ну, може, ця версія трохи менш заплутана. ;)
Фалько

2
Я плутав вищезгаданий вихід. обидва start і startAndExpand мають однаковий вихід. Яка різниця між ними? Ви можете дати пояснення, якщо це можливо ..
Ранджіт Кумар

1
FillAndExpandце те, що ти хочеш, 99% часу
Стефан Делькро

1
@RanjithKumar Вони однакові. Це StackLayout було вкладено в інший батько, тоді його FillAndExpand може змінити значення - він розшириться в межах свого батьківського.
Михай Маркич

16

У поточній версії Xamarin.Forms є трохи помилок; можливо, це вже було деякий час.

CenterAndExpand як правило, не розширюється, а робота над цим може бути заплутаною.

Наприклад, якщо у вас StackLayoutвстановлено значення CenterAndExpand, тоді ви помістите мітку, яка також встановлена, CenterAndExpandви очікуєте, що мітка буде на повну ширину StackLayout. Ні. Він не розшириться. Вам потрібно встановити StackLayout" FillAndExpand", щоб вкладений об'єкт Label розширити на повну ширину StackLayout, а потім сказати мітці зосереджувати текст, а не сам як об'єкт HorizontalTextAlignment="Center". На мій досвід, вам потрібно налаштувати і батьківського, і вкладеного дитини, FillAndExpandякщо ви дійсно хочете переконатися, що він розширюється, щоб він підходив.

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />

3
"... ви очікуєте, що мітка, яка на повну ширину StackLayout." Це припущення є неправильним. Expandвикористовується лише для дітей програми StackLayout. Отже, якщо ваш StackLayout є коренем, або він не знаходиться в іншому StackLayout, Expandце не впливає. Натомість, будь-яка опція, крім Fill, буде виконувати функції "обгортання вмісту" для розміру розмірів, що саме ви бачите.
therealjohn

Крім того, розширення працює лише для LayoutOptions, які мають однакову орієнтацію StackLayout. У цьому випадку макет є "вертикальним", але розглядаються варіанти горизонтальні (протилежності).
therealjohn

Термін "AndExpand" неоднозначний. Це можна трактувати як "максимально розширити" або "розширити лише наскільки це потрібно". Я думаю, що Microsoft повинна змінити умови на щось менш заплутане, наприклад, "CenterAndExpandToParent" або "CenterAndExpandAsNeeded"
technoman23

1

Фалько дав хороше пояснення, але я хотів додати це ще з іншим візуальним і як ці теги працюють у xaml, саме цим я вважаю за краще використовувати більшу частину часу. Я створив простий проект для тестування результатів відображення. Ось 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="Alignments.MainPage"
             BackgroundColor="White">


    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="1" Margin="30">
        <Label Text="Vert: EndAndExpand, Horz: EndAndExpand" VerticalOptions="EndAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="White"/>
    </StackLayout>


</ContentPage>

Як бачите, це дуже простий StackLayout з міткою всередині. Для кожного зображення нижче я зберігав StackLayout однаковим, я просто змінив горизонтальну та вертикальну параметри введення та змінив текст, щоб він відображав вибрані параметри, так що ви можете побачити, як запис переміщується та змінюється розмір.

Почати проти StartAndExpand Ось код, який використовується для запуску:

<Label Text="Vert: Start, Horz: Start" VerticalOptions="Start" HorizontalOptions="Start" BackgroundColor="White"/>

І код, який використовується для StartAndExpand:

<Label Text="Vert: StartAndExpand, Horz: StartAndExpand" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" BackgroundColor="White"/>

Як ви бачите, немає візуальної різниці, крім того, що в опції StartAndExpand використовується більше тексту. Це було перевірено на моєму фізичному пристрої Samsung A30. Вони можуть відображатися по-різному на різних пристроях, але я думаю, що всі зображення тут колективно показують, що в Xamarin є деякі помилки. Для решти я лише покажу скріншоти, я думаю, що вони пояснюють себе.

Кінець проти EndAndExpand

Центр проти CenterAndExpand

Fill vs FillAndExpand

Я також рекомендую поглянути на документацією Microsoft для отримання додаткових деталей. Примітно те, що "Розширення використовується лише StackLayout".


Приємна візуалізація. Але я не бачу, чому це повинно показувати помилки в Xamarin. Що може бентежити, що етикетки можуть займати більше місця, ніж їх білий фон (сірий регіони в моєму прикладі). Отже, мітка "Центр Верта" зосереджена в просторі, який він займає - не на всій сторінці. Мабуть, після майже шести років ця тема все ще настільки заплутана, як і назад.
Фалько
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.