본문 바로가기
깡샘 코틀린

07-4 표 형태로 배치 - GridLayout

by 농농씨 2023. 6. 20.

GridLayout 배치 규칙

GridLayout은 행과 열로 구성된 테이블 화면을 만드는 레이아웃 클래스이다. LinearLayout처럼 orientation 속성으로 가로나 세로 방향으로 뷰를 나열하는데 LinearLayout과 다르게 줄바꿈을 자동으로 해준다.

  • orientation: 방향 설정
  • rowCount: 세로로 나열할 뷰 개수
  • columnCout: 가로로 나열할 뷰 개수

GridLayout 역시 LinearLayout처럼 orientation 속성으로 방향을 설정하고 그 방향대로 뷰를 나열한다. 그런데 rowCountcolumnCount 속성에 설정한 개수만큼 뷰를 추가하면 자동으로 줄바꿈하여 그 다음 줄에 뷰를 출력한다.

GridLayout에 orientation 속성을 가로로 지정하고 그 아래에 버튼을 5개 추가해보겠다.

이때 GridLayout에 추가한 뷰의 크기는 기본으로 wrap_content로 지정되므로 layout_width, layout_height 속성을 설정하지 않아도 오류가 발생하지 않는다. 

// GridLayout으로 버튼 5개 출력
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" // 수평으로 출력되게 함
    <Button android:text="A" />
    <Button android:text="B" />
    <Button android:text="C" />
    <Button android:text="D" />
    <Button android:text="E" /> // 버튼들 별도의 크기속성 지정하지 않았음
</GridLayout>

실행해보면 abcde 버튼 다섯개가 가로로 꽉채워지는 대신 마지막 버튼이 옆으로 짤림

이제 여기에 columnCount 속성을 추가해보겠다. 

// 열 개수 지정
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" // 수평으로 출력되게 함
    android:columnCount="3" // 열 속성을 3으로 지정함
    <Button android:text="A" />
    <Button android:text="B" />
    <Button android:text="C" />
    <Button android:text="D" />
    <Button android:text="E" /> 
</GridLayout>

실행해보면

A B C

D E 

이렇게 됨

columnCount값을 3으로 지정했으므로 가로 방향으로 뷰를 3개 출력하고 그 다음줄에 나머지 뷰 2개를 출력한다.

orientation값이 horizontal이면 columnCount 속성으로, vertical 속성이면 rowCount 속성으로 줄바꿈 한다. 

다음은 세로 방향으로 rowCount 속성을 추가해보겠다.

// 행 개수 지정
// 열 개수 지정
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" // 수직으로 출력되게 함
    android:rowCount="3" // 행 속성을 3으로 지정함
    <Button android:text="A" />
    <Button android:text="B" />
    <Button android:text="C" />
    <Button android:text="D" />
    <Button android:text="E" /> 
</GridLayout>

이렇게 하면 실행결과는

A  D

B  E

C

처럼 ABC 가 세로로 먼저 나열되고 행 속성인 3을 충족하므로 그 오른쪽으로 자동 줄바꿈 돼서 나머지 뷰인 D, E가 출력된다.

 

GridLayout 속성

특정 뷰의 위치 조정하기

GridLayout으로 뷰를 배치하면 추가한 순서대로 배치되는데, layout_row, layout_column 속성을 이용하면 특정 뷰의 위치를 조정할 수 있다.

  • layout_row: 뷰가 위치하는 세로 방향 인덱스
  • layout_column: 뷰가 위치하는 가로 방향 인덱스
// 뷰의 위치 조정
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:columnCount="3" 
    <Button android:text="A" />
    <Button android:text="B" />
    <Button android:text="C" 
    	android:layout_row="1" // 주목!
        android:layout_column="1" /> // 주목!
    <Button android:text="D" />
    <Button android:text="E" /> 
</GridLayout>

실행결과

A  B

    C  D

E

원래 C 버튼이 B 버튼 옆에 와야한다. 그런데 C 버튼에 layout_row="1"과 layout_column="1"로 속성을 지정해 위치를 변경했다. 이렇게 하면 이후에 추가한 뷰는  지정한 위치 다음부터 나온다.   

 

특정 뷰의 크기 확장하기

GridLayout을 이용하면서 다음처럼 특정 뷰의 크기를 확장해야 할 때가 있다. 

A  HelloWorld HelloWorld  C

D  E                                      F

예시에서 두번째 칸의 뷰가 크게 출력되었다. (HelloWorld HelloWorld) 뷰의 내용이 길어서 크게 출력되는 것은 문제가 없지만 이 때문에 E버튼이 출력된 칸에 여백이 생겨버렷다(!)

만약 E 버튼을 두번째 버튼 크기만큼 확대해서 출력하려면 layout_gravity 속성을 이용한다.

// 뷰의 크기 확장하기
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:columnCount="3"
    <Button android:text="A" />
    <Button android:text="HELLOWORLD HELLOWORLD" />
    <Button android:text="C" />
    <Button android:text="D" 
    	android:layout_gravity="fill_horizontal" /> // 얘를 늘려서 가로로 채우라는 뜻
    <Button android:text="E" /> 
</GridLayout>

실행결과

  A   HELLOWORLD HELLOWORLD    C

  D                            E                             F

layout_gravity="fill_horizontal"로 특정 뷰를 확장해서 출력해보았다.

그런데 공간이 충분하다면 여백에 다음 뷰를 넣어 한 칸에 뷰를 2개 표시할 수도 있다.

// 여백에 다음 뷰 넣기
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" 
    android:columnCount="3" 
    <Button android:text="A" />
    <Button android:text="HELLOWORLD HELLOWORLD" />
    <Button android:text="C" />
    <Button android:text="D" />
    <Button android:text="E" /> 
    <Button android:text="F" 
    	android:layout_row="1" // 주~
        android:layout_column="1"
        android:layout_gravity="right" />  // 목!
</GridLayout>

실행결과

  A   HELLOWORLD HELLOWORLD    C

  D       E                                     F.    

layout_row, layout_column 속성으로 F와 E 버튼을 같은 칸에 표시했다. (?? 미는 역할 아니었나 0부터 시작인... 그런 위치였을뿐인거군 마치 좌표처럼....) 그런데 이렇게 같은 칸에 표시하면 뷰가 겹치므로 layout_gravity 속성으로 정렬 위치를 지정해줘야 한다. 예에서는 F 버튼을 오른쪽으로 정렬했다.

 

열이나 행 병합하기 

마지막으로 어떤 뷰가 테이블에서 여러 칸을 차지하게 설정할 수 있다. 

이때 layout_columnSpan, layout_rowSpan 속성을 사용한다.

  • layout_columnSpan: 가로로 열 병합
  • layout_rowSpan: 세로로 행 병합
// 열과 행 병합
<GridLayout xmlns:android="http//schemas:android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" 
    android:columnCount="3" 
    <Button android:text="A" 
    	android:layout_columnSpan="2" // 가로로 2칸 차지하게
        android:layout_rowSpan="2" // 세로로 2칸 차지하게
        android:layout_gravity="fill"/> // ? 이해안됨
    <Button android:text="B" />
    <Button android:text="C" />
    <Button android:text="D" />
    <Button android:text="E" /> 
    <Button android:text="F" />
</GridLayout>

실행결과

A B
C
D E F

A 버튼은 ~Span 속성값을 모두 2로 설정해서 총 네칸을 차지하게 된다. 

(fill)이 먼말인지 이해가 안가는데

 

cf.TableLayout도 있다. 편한대로 선택하면 되지만, TableLayout은 앱이 실행되다가 셀의 개수가 변하면 해을 일일이 계산해서 TableRow를 지정해야 한다는 단점이 있다. 그런데 GridLayout에서는 방향과 개수만 설정하면 알아서 행이 결정된다.