Xamarin.Form의 LayoutOptions, 특히 채우기 및 확장의 차이점은 무엇입니까?


170

Xamarin.Forms에는 every 와 View두 가지 속성이 있습니다. 둘 다 유형 이며 다음 값 중 하나를 가질 수 있습니다.HorizontalOptionsVerticalOptionsLayoutOptions

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

분명히 상위 뷰에서 뷰의 정렬을 제어합니다. 그러나 각 개별 옵션의 동작은 정확히 어떻게됩니까? 그리고 Fill접미사와의 차이점은 무엇 Expand입니까?

답변:


335

짧은 답변

Start, Center, EndFill뷰의 정의 의 공간에 정렬 .

Expand사용 가능한 경우 더 많은 공간을 차지하는지 여부를 정의 합니다 .

이론

구조 LayoutOptions는 두 가지 별개의 동작을 제어합니다.

  1. 정렬 : 상위 뷰 내에서 뷰가 어떻게 정렬됩니까?

    • Start: 세로 정렬의 경우보기가 맨 위로 이동합니다. 수평 정렬의 경우 일반적으로 왼쪽입니다. (단, 오른쪽에서 왼쪽으로 언어가 설정되어있는 장치에서는 다른 방법, 즉 오른쪽 정렬입니다.)
    • Center: 뷰가 중앙에 있습니다.
    • End: 일반적으로보기가 아래쪽 또는 오른쪽으로 정렬됩니다. (물론 오른쪽에서 왼쪽으로 쓰는 언어에서는 왼쪽 정렬됩니다.)
    • Fill:이 정렬은 약간 다릅니다. 뷰는 부모 뷰의 전체 크기로 확장됩니다.

    그러나 부모가 자식보다 크지 않으면 해당 정렬 사이에 차이가 없습니다. 정렬은 사용 가능한 추가 공간이있는 부모 뷰에만 중요합니다.

  2. 확장 : 가능한 경우 요소가 더 많은 공간을 차지합니까?

    • 접미사 Expand: 상위 뷰가 모든 하위의 결합 된 크기보다 큰 경우, 즉 추가 공간을 사용할 수있는 경우 해당 접미사가있는 하위 뷰 사이에 공간이 비례합니다. 그 아이들은 자신의 공간을 "사용"하지만 반드시 "채우지"는 않습니다. 아래 예제에서이 동작을 살펴 보겠습니다.
    • 접미사 없음 : Expand접미사가없는 어린이 는 사용 가능한 공간이 더 있어도 추가 공간을 얻지 못합니다.

    다시 말하지만 부모 뷰가 자식 뷰보다 크지 않으면 확장 접미사도 아무런 차이가 없습니다.

다음 예제에서 8 가지 레이아웃 옵션의 차이점을 살펴 보겠습니다.

앱에는 StackLayout8 개의 중첩 된 흰색 버튼 이있는 짙은 회색이 있으며 각 버튼에는 세로 레이아웃 옵션이 표시되어 있습니다. 버튼 중 하나를 클릭하면 세로 레이아웃 옵션이 스택 레이아웃에 할당됩니다. 이런 식으로 서로 다른 레이아웃 옵션을 사용하여 뷰와 부모와의 상호 작용을 쉽게 테스트 할 수 있습니다.

(마지막 몇 줄의 코드는 노란색 상자를 추가합니다. 잠시 후 다시 올 것입니다.)

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,
        });
    }
}

다음 스크린 샷은 8 개의 각 버튼을 클릭했을 때의 결과를 보여줍니다. 우리는 다음을 관찰합니다.

  • 부모 stackLayout가 타이트한 경우 ( Fill페이지 는 아님 ) 각각의 세로 레이아웃 옵션 Button은 무시할 수 있습니다.
  • 수직 레이아웃 옵션 stackLayout은 크기가 더 크고 (예 : Fill정렬을 통해 ) 개별 버튼에 Expand접미사 가있는 경우에만 중요합니다 .
  • 추가 공간은 결국 Expand접미사가있는 모든 버튼 사이에 비례합니다 . 이를보다 명확하게 확인하기 위해 인접한 두 버튼 사이에 노란색 수평선을 추가했습니다.
  • 요청한 높이보다 더 많은 공간이있는 버튼이 반드시 "채우는"것은 아닙니다. 이 경우 실제 동작은 해당 정렬에 의해 제어됩니다. 예를 들어 공간의 상단, 중앙 또는 버튼에 정렬되거나 완전히 채워집니다.
  • 모든 버튼은 레이아웃의 전체 너비에 걸쳐 VerticalOptions있습니다.

스크린 샷

여기에 해당 고해상도 스크린 샷이 있습니다.


6
이미지는 [[midfing]], lol처럼 보입니다. 그냥 농담 정말 도움이되었다
조이 렉스

1
@JoyRex : 글쎄요, 아마도이 버전 은 약간 덜 혼란 스럽습니다. ;)
Falko

2
위의 출력과 혼동되었습니다. start & startAndExpand는 모두 동일한 출력입니다.이 둘의 차이점은 무엇입니까? 가능하다면 설명을
해주시겠습니까?

1
FillAndExpand당신이 원하는 것, 시간의 99 %
Stephane Delcroix

1
@RanjithKumar 그들은 동일합니다. 그것은 StackLayout는 다음의 FillAndExpand 차이를 만들 수있는 다른 부모에 중첩 된 - 그것은 내에서 확장 할 부모입니다.
Miha Markic

16

현재 버전의 Xamarin.Forms에는 약간의 버그가 있습니다. 어쩌면 거기에 있었을 것입니다.

CenterAndExpand 일반적으로 확장되지 않으며 해결 방법이 혼란 스러울 수 있습니다.

예를 들어로 StackLayout설정 한 CenterAndExpand경우 그 안에 레이블을 넣으면 CenterAndExpand전체 너비 인 레이블이 필요합니다 StackLayout. 아니. 확장되지 않습니다. 중첩 된 Label 객체가 전체 너비로 확장되도록하려면 StackLayout" FillAndExpand"을 ( 를) 설정 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의 전체 너비 인 레이블이 필요합니다." 이 가정은 올바르지 않습니다. ExpandStackLayout의 하위 항목에만 사용됩니다. 따라서 StackLayout이 루트이거나 다른 StackLayout에 Expand없는 경우 아무런 영향을 미치지 않습니다. 대신 채우기 이외의 옵션은 크기 조정을위한 "컨테이너 랩핑"역할을합니다.
therealjohn

또한 확장은 StackLayout과 동일한 방향 인 LayoutOptions에만 작동합니다. 이 경우 레이아웃은 "수직"이지만 해당 옵션은 가로 (반대)입니다.
therealjohn

"AndExpand"라는 용어는 모호합니다. "가능한 한 확장"또는 "필요한만큼 확장"으로 해석 될 수 있습니다. Microsoft는 "CenterAndExpandToParent"또는 "CenterAndExpandAsNeeded"와 같이 덜 혼동스러운 용어로 용어를 변경해야한다고 생각합니다.
technoman23

1

Falko는 좋은 설명을했지만 다른 시각 효과와 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>

보시다시피 내부에 Label이있는 매우 간단한 StackLayout입니다. 아래의 각 이미지에 대해 StackLayout을 동일하게 유지하면서 항목의 가로 및 세로 옵션을 변경하고 선택한 옵션을 표시하도록 텍스트를 변경하여 항목이 어떻게 이동하고 크기가 조정되는지 확인할 수 있습니다.

시작 대 시작 및 확장 시작에 사용 된 코드는 다음과 같습니다.

<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에 버그가 있음을 총괄적으로 보여줍니다. 나머지 부분에서는 스크린 샷을 보여 드리겠습니다. 자기 설명이라고 생각합니다.

끝 대 끝 및 확장

센터 대 CenterAndExpand

채우기 대 채우기 및 확장

또한 자세한 내용 은 Microsoft 설명서 를 참조하십시오. 주목할만한 것은 "확장은 StackLayout에 의해서만 사용된다"는 것입니다.


멋진 시각화. 그러나 이것이 왜 Xamarin에서 버그를 보여야하는지 모르겠습니다. 혼란 스러울 수있는 것은 레이블이 흰색 배경 (예제에서 회색 영역)보다 더 많은 공간을 차지할 수 있다는 것입니다. 따라서 "Vert Center"레이블은 전체 페이지가 아닌 차지하는 공간의 중앙에 위치합니다. 거의 6 년이 지난 후에도이 주제는 이전보다 여전히 혼란 스럽습니다.
Falko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.