Layout 기본 (1) - Grid

Grid는 뷰를 행과 열의 관점에서 정렬한다. 행과 열은 비율적 또는 절대적인 크기가 될 수 있다. Grid는 전통적인 테이블형식의 데이터를 다루기 위한것과 혼돈하지 마라. Grid는 순수하게 컨텐츠의 레이아웃을 다루는 목적으로 존재한다.
Grid Layout

목적

Grid는 뷰를 격자형태로 정렬하는데 사용될 수 있다.

  • 계산기 앱의 버튼 정렬
  • 버튼이나 아이콘을 iOS 또는 Android의 홈스크린과 같이 배치
  • 일차원적인 공간에 동일한 크기의 뷰를 나열 (툴바와 같은 형태)

사용법

테이블과 달리, Grid는 행과 열의 크기나 갯수가 컨텐츠에 의해 결정되지 않는다. 대신, Grid는 RowDefinitions와 ColumnDefinitions 컬렉션을 가진다. 이 정의들은 몇개의 행과 열이 놓여질지에 관한 정보를 가지고 있다. 뷰요소는 특정 행과 열의 번호에 기반해 정해진 곳에 추가된다.

행과 열

RowDefinitions은 Height속성을 갖고, ColumnDefinition은 Width라는 속성을 가진다. 높이와 너비는 다음의 선택값을 가질 수 있다.

  • Auto - 행 또는 열에 컨텐츠의 크기에 따라 크기가 자동으로 정해진다. GridUnitType.Auto 또는 Auto 를 사용한다.
  • 비례항() - 크기를 남은 공간의 비율에 따라 정한다. GridUnitType.Star 또는 “#“ 과 같이 XAML에서 사용할 수 있다. “#”은 원하는 배율의 숫자로 치환된다. “*”로만 사용되었을 경우에는 가능한 공간만큼 채워진다.
  • 절대값 - 정해진 높이나 너비값으로 크기가 정해진다. GridUnitType.Absolute 또는 특정 숫자값을 사용한다.

주의: Xamarin.Forms 에서 너비의 기본값은 Auto이다. 이 크기는 자식 컴포넌트의 크기에 따라 결정된다는것을 의미한다. Microsoft 플랫폼의 XAML 구현체에서는 이와 달리 “*”가 기본값이다. 이것은, 사용가능한 공간을 모두 채운다.

예를들어, 어떤 앱이 세개의 행과 두개의 컬럼으로 구성된다고 가정하자. 마지막 행은 정확히 200px의 높이를 가지고, 맨윗줄은 가운데행 보다 두배 높다. 마지막으로, 맨왼쪽 열은 컨텐츠의 폭만큼 너비를 차지하고 오른쪽은 나머지 공간을 차지한다고 했을때 XAML을 아래와 같이 작성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>

C# 에서는 아래와 같다.

1
2
3
4
5
var grid = new Grid();
grid.RowDefinitions.Add (new RowDefinition { Height = new GridLength(2, GridUnitType.Star) });
grid.RowDefinitions.Add (new RowDefinition { Height = new GridLength (1, GridUnitType.Star) });
grid.RowDefinitions.Add (new RowDefinition { Height = new GridLength(200)});
grid.ColumnDefinitions.Add (new ColumnDefinition{ Width = new GridLength (200) });

뷰를 Grid에 삽입하기

뷰를 Grid에 추가하려면, 뷰를 Grid의 자식으로서 어떤 행과 열에 속할지를 명시하여 추가하면 된다. XAML에서는 Grid.Row와 Grid.Column 을 Zero-base로 추가한다. 즉, 4x4격자의 경우 좌상단 셀의 경우 (0,0)이 되고 우하단 셀은 (3,3)이 된다는것을 의미한다.
아래 Grid의 경우 코드를 보자.
4x4 Grid

XAML 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Top Left" Grid.Row="0" Grid.Column="0" />
<Label Text="Top Right" Grid.Row="0" Grid.Column="1" />
<Label Text="Bottom Left" Grid.Row="1" Grid.Column="0" />
<Label Text="Bottom Right" Grid.Row="1" Grid.Column="1" />
</Grid>

C# 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star)});
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star)});
var topLeft = new Label { Text = "Top Left" };
var topRight = new Label { Text = "Top Right" };
var bottomLeft = new Label { Text = "Bottom Left" };
var bottomRight = new Label { Text = "Bottom Right" };
grid.Children.Add(topLeft, 0, 0);
grid.Children.Add(topRight, 0, 1);
grid.Children.Add(bottomLeft, 1, 0);
grid.Children.Add(bottomRight, 1, 1);

위 코드는 네개의 레이블을 동일한 크기를 가지는 두개의 컬럼과 행으로 이루어진 격자에 위치시킨다. GridUnitType.Star 이기 때문에 각 레이블은 가능한 공간 만큼 늘어난다.

공백

Grid는 행과 열사이의 공백을 제어할 수 있는 속성을 갖고 있다.

  • ColumnSpacing - 열사이의 공백
  • RowSpacing - 행사이의 공백

다음 코드는 한행에 두개의 열로 구성되어 있으며, 컬럼사이의 간격은 5px을 할당하였다.

1
2
3
4
5
6
<Grid ColumnSpacing="5">
<Grid.ColumnDefinitions>
<ColumnDefinitions Width="*" />
<ColumnDefinitions Width="*" />
</Grid.ColumnDefinitions>
</Grid>

C# 코드

1
2
3
var grid = new Grid { ColumnSpacing = 5 };
grid.ColumnDefnitions.Add(new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star)});
grid.ColumnDefnitions.Add(new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star)});

Spans

Grid를 사용하다보면, 어떤 요소의 경우 한칸 이상의 행이나 열을 차지할 필요가 생길때가 있다. 아래의 계산기 앱을 보자.
CalcApp Grid

“0”버튼이 두개의 컬럼을 사용하고 있다. 이것은 ColumnSpan 속성을 사용하면 된다. 이 속성은 몇개의 컬럼을 차지할지를 정한다.

1
<Button Text = "0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" />

C# 코드

1
2
3
Button zeroButton = new Button { Text = "0" };
controlGrid.Children.Add (zeroButton, 0, 4);
Grid.SetColumnSpan (zeroButton, 2);

RowSpan도 동일한 방법으로 적용할 수 있다.

출처 : https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/grid/