안드로이드 앱은 다양한 뷰를 적절하게 배치해서 화면을 구성한다.
이때 뷰를 배치하는 클래스를 레이아웃 클래스라고 한다.
레이아웃 클래스는 그릇의 역할을 한다.
레이아웃 클래스는 저마다 배치 규칙이 있다.
LinearLayout은 뷰를 가로나 세로 방향으로 나열하는 레이아웃 클래스다.
orientation 속성에 horiziontal 또는 vertical을 설정할 수 있다.
LinearLayout은 방향만 설정하면 뷰를 추가한 순서대로 나열한다.
만약 사진과 같은 화면을 구성해야 한다면 LinearLayout으로 구현할 수 있을까?
이 화면을 구성하려면 1개의 이미지 뷰와 3개의 텍스트 뷰가 필요하다.
그런데 만약 orientation을 horizontal로 지정하면 모든 뷰가 일렬로 표시될 것이다.
이럴 때는 LinearLayout을 중첩하면 가능하다.
레이아웃 클래스도 뷰이므로 다른 레이아웃 클래스에 포함할 수 있다.
즉, LinearLayout에 LinearLayout을 포함할 수 있다.
이처럼 LinearLayout은 특정한 방향으로 뷰를 배치하는 단순한 레이아웃이지만 레이아웃을 중첩할 때 진가를 발휘한다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="BUTTON1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="BUTTON2" />
</LinearLayout>
layout_weight는 동일한 부모 레이아웃 내에서 자식 뷰 간의 비율을 나타낸다.
예를 들어, 두 개의 뷰가 각각 layout_weight="1"과 layout_weight="3"을 가진다면, 전체 가용 공간은 1 + 3 = 4로 계산된다.
그런 다음, 첫 번째 뷰는 전체 공간의 1/4(25%)을 차지하고, 두 번째 뷰는 3/4(75%)을 차지하게 된다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="BUTTON1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="BUTTON2" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="BUTTON3" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BUTTON4" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button1" />
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button2" />
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button3" />
</LinearLayout>
뷰를 정렬할 때는 gravity와 layout_gravity를 사용한다.
만약 이 속성을 사용하지 않으면 기본값은 left/top이다. 즉, 왼쪽 위를 기준으로 정렬한다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#FF0000"
android:text="HelloWorld"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:textStyle="bold" />
</LinearLayout>
현재는 gravity 설정을 안했기 때문에 기본값인 왼쪽 위에 정렬되었다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:background="#FF0000"
android:gravity="right|bottom"
android:text="HelloWorld"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:textStyle="bold" />
</LinearLayout>
gravity: 정렬 대상은 콘텐츠다. "HelloWorld" 문자열이 텍스트 뷰가 차지하는 영역에서 오른쪽 아래에 표시된다.
layout_gravity: 뷰 자체를 정렬한다. 따라서 텍스트 뷰 자체(빨간색 박스)가 가로로 가운데에 표시된다.
orientation="vertical"
:
LinearLayout
에서 orientation
속성은 자식 뷰들이 어떻게 배치될지를 결정한다.vertical
로 설정하면 자식 뷰들이 세로로 위에서 아래로 배치된다. 이때 자식 뷰들은 기본적으로 가로 방향으로 꽉 채워지며, 세로 방향으로는 순서대로 쌓인다.layout_gravity
:
layout_gravity
는 자식 뷰가 부모 LinearLayout
내에서 어떻게 배치될지를 결정한다.layout_gravity="center_horizontal"
은 자식 뷰를 가로 방향 중앙에 배치한다. 이 속성은 자식 뷰의 위치를 부모 레이아웃 안에서 지정할 때 사용한다.왜 layout_gravity="center_vertical"
이 적용되지 않나?:
LinearLayout
이 세로 방향(orientation="vertical"
)으로 설정된 경우, 자식 뷰는 이미 위에서 아래로 배치된다. 즉, 세로 방향으로는 이미 LinearLayout
이 기본적으로 자식 뷰의 배치를 결정하고 있기 때문에, 추가적인 세로 정렬(center_vertical
)은 효과가 없다.center_horizontal
)은 부모 레이아웃 안에서 자식 뷰를 가로로 가운데에 배치할 수 있다. 정리:
LinearLayout
의 orientation
속성에 따라 layout_gravity
의 적용 범위가 달라진다.vertical
)으로 설정된 LinearLayout
에서는 layout_gravity="center_vertical"
이 이미 세로 배치가 고정되어 있어 의미가 없고, 가로 방향(horizontal
)의 정렬만 영향을 미친다.이번에는 빨간 박스를 화면의 정가운데에 위치시키려고 한다.
뷰를 화면 가운데에 표시하려면 레이아웃에 gravity="center"로 설정해야 한다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#FF0000"
android:gravity="right|bottom"
android:text="HelloWorld"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:textStyle="bold" />
</LinearLayout>
코드에서 android:layout_gravity="center_horizontal"을 제거했다.
왜냐하면 이미 LinearLayout의 부모 레이아웃에서 android:gravity="center"를 사용하여 자식 뷰들을 화면 중앙으로 정렬했기 때문에 중복이기 때문이다.