Android

뷰 배치 레이아웃

9tun 2025. 7. 2. 22:11

레이아웃 클래스는 다른 뷰 객체를 담는 그릇 역할을 합니다.

안드로이드의 대표적인 레이아웃 클래스 5가지를 살펴보시죠!

 

선형 배치: LinearLayout

뷰를 가로나 세로로 나열하는 레이아웃 클래스입니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">	/* 이 부분이죠 */

    <Button
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "BUTTON1"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text = "BUTTON2"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">	/* 이 부분이죠 */
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text = "BUTTON3"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text = "BUTTON4"/>
    </LinearLayout>

</LinearLayout>

 

방향 설정을 해두면, 뷰를 추가하면 그 방향으로 순서대로 나열됩니다.

화면에서 벗어나도 줄을 바꾸지 않죠 ^^;;

사진 오른쪽에 아이디와 상태메시지는 가로로 배치되어 있습니다.

가로와 세로가 중첩된 구조입니다.

이럴 때는 가로로 배치하는 LinearLayout에 세로로 배치하는 LinearLayout을 하나의 요소로 넣으면 됩니다.

이미 앞 예제에서도 그 비슷한 구조가 나왔죠. 

 

여백 채우기: layout_weight

layout_weight은 안드로이드의 LinearLayout에서 여백 또는 공간을 비율로 분배할 때 사용하는 속성입니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">

<EditText
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:hint="내용 입력" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="전송" />
</LinearLayout>

EditText가 여백을 채우니 그럴싸하다

뷰 여러개로 여백 채우기

layout_weight을 여러 뷰에 동시에 적용하면, 여백을 각 뷰가 비율대로 나눠 가집니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="3"
    android:text="왼쪽" />

<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="2"
    android:text="가운데" />

<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="오른쪽" />
</LinearLayout>

 

중첩된 레이아웃에서 여백 채우기

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 내부 가로 레이아웃 -->
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="내용 입력" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="전송" />
</LinearLayout>

<!-- 여백용 뷰 (남은 공간 채움) -->
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="중간 버튼"
        android:layout_weight="1" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="아래 버튼" />

</LinearLayout>

뷰 정렬: gravity, layout_gravity

속성 의미 적용 대상
gravity 뷰 안의 콘텐츠(텍스트, 이미지) 정렬 TextView, Button 등
layout_gravity 뷰 자체가 부모 레이아웃 안에서 어디 위치할지 LinearLayout, FrameLayout 등

이 속성을 이용하지 않으면 기본값은 왼쪽 위가 기준입니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:background="#EEEEEE">

<!-- 예시 1: gravity 사용 -->
<TextView
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:gravity="right|bottom"
    android:background="#FFCDD2"
    android:text="gravity → 내부 정렬" />

<!-- 예시 2: layout_gravity 사용 -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:background="#BBDEFB"
    android:text="layout_gravity → 뷰 위치" />
</LinearLayout>

 

🙋🏻‍♂️ 뷰를 화면 정중앙에 배치하려면 어떻게 하나요?

👨🏻‍🏫두 가지 방법을 사용할 수 있죠!

 

✅ 방법 1: LinearLayout에서 gravity="center"

부모 gravity를 사용하면, 그 하위 자식 뷰를 정렬할 수 있죠.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="정중앙" />
</LinearLayout>

 

✅ 방법 2: FrameLayout에서 layout_gravity="center"

뷰 자체를 부모 레이아웃 중앙에 배치할 수도 있고요.

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="정중앙" />
</FrameLayout>

 


상대 위치로 배치: RelativeLayout

 

RelativeLayout 배치 규칙

RelativeLayout은 다른 뷰를 기준으로 배치합니다.

→ 부모 또는 형제 뷰를 기준으로 위, 아래, 왼쪽, 오른쪽, 중앙 등에 배치할 수 있습니다.

 

RelativeLayout은 다른 뷰의 id를 기준으로 뷰를 배치합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 기준이 되는 첫 번째 버튼 -->
<Button
    android:id="@+id/btnBase"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="기준 버튼"
    android:layout_marginTop="50dp"
    android:layout_marginStart="50dp" />

<!-- 기준 버튼 오른쪽에 배치되는 두 번째 버튼 -->
<Button
    android:id="@+id/btnRight"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="오른쪽 버튼"
    android:layout_toRightOf="@id/btnBase"
    android:layout_alignTop="@id/btnBase"
    android:layout_marginStart="16dp" />

</RelativeLayout>

 

✅ 부모 기준 배치 속성

속성명 설명
layout_alignParentTop="true" 부모 위쪽에 정렬
layout_alignParentBottom="true" 부모 아래쪽에 정렬
layout_alignParentStart="true" 부모 왼쪽에 정렬 (RTL 대응)
layout_alignParentEnd="true" 부모 오른쪽에 정렬 (RTL 대응)
layout_alignParentLeft="true" 부모 왼쪽에 정렬 (권장X, 대신 Start 사용)
layout_alignParentRight="true" 부모 오른쪽에 정렬 (권장X, 대신 End 사용)
layout_centerInParent="true" 부모 중앙에 정렬
layout_centerHorizontal="true" 부모 가로 중앙에 정렬
layout_centerVertical="true" 부모 세로 중앙에 정렬

 

✅ 2. 형제(다른 뷰) 기준 배치 속성

속성명 설명
layout_above="@id/view" 해당 뷰 위에 배치
layout_below="@id/view" 해당 뷰 아래에 배치
layout_toLeftOf="@id/view" 해당 뷰 왼쪽에 배치
layout_toRightOf="@id/view" 해당 뷰 오른쪽에 배치
layout_alignTop="@id/view" 해당 뷰와 위쪽 정렬
layout_alignBottom="@id/view" 해당 뷰와 아래쪽 정렬
layout_alignStart="@id/view" 해당 뷰와 왼쪽 정렬 (RTL 대응)
layout_alignEnd="@id/view" 해당 뷰와 오른쪽 정렬 (RTL 대응)
layout_alignLeft="@id/view" 해당 뷰와 왼쪽 정렬 (권장X)
layout_alignRight="@id/view" 해당 뷰와 오른쪽 정렬 (권장X)

 


겹쳐서 배치: FrameLayout

✅ FrameLayout 배치 규칙 요약

  • 뷰를 겹쳐서 배치하는 레이아웃입니다.
  • 기본 위치는 좌측 상단이며,
  • 나중에 선언된 뷰가 위에 표시됩니다.
  • layout_gravity 속성으로 위치를 조정할 수 있으나, 뷰들은 여전히 겹쳐진 상태입니다.

✅ 화면 제어 방식

  • 실제 앱에서는 모든 뷰를 올려두고,
  • 필요한 순간에 visibility 속성으로 하나만 보여줍니다.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 콘텐츠 뷰 -->
    <TextView
        android:id="@+id/contentView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="콘텐츠 화면"
        android:textSize="24sp"
        android:visibility="visible" />

    <!-- 로딩 뷰 -->
    <ProgressBar
        android:id="@+id/loadingView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone" />
    <!--마지막 줄을 android:visibility="visible"로 바꿔보세요 -->

    <!-- 에러 뷰 -->
    <TextView
        android:id="@+id/errorView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="에러 발생!"
        android:textColor="#FF0000"
        android:textSize="24sp"
        android:visibility="gone" />
    <!--마지막 줄을 android:visibility="visible"로 바꿔보세요 -->

</FrameLayout>


표 형태로 배치: GridLayout

표처럼 행(row)과 열(column) 을 기준으로 뷰를 배치하는 Android 레이아웃입니다.

 

orientation으로 방향을 설정하고, 그 방향대로 뷰를 나열합니다.

rowCount, columnCount를 기준으로 초과한 뷰는 자동 줄바꿈 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="3"
android:orientation="horizontal">

<Button android:text="버튼1"/>
<Button android:text="버튼2"/>
<Button android:text="버튼3"/>
<Button android:text="버튼4"/>
<Button android:text="버튼5"/>

</GridLayout>

 

GridLayout 속성

layout_row, layout_column 속성으로 특정 뷰의 위치를 조정할 수 있습니다.

속성 설명
layout_row 뷰가 위치할 행 번호 (0부터 시작)
layout_column 뷰가 위치할 열 번호 (0부터 시작)

 

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="3"
android:orientation="horizontal">

<Button android:text="버튼1"/>
<Button android:text="버튼2"/>

<Button
    android:text="버튼3"
    android:layout_row="1"
    android:layout_column="1"/>

<Button android:text="버튼4"/>
<Button android:text="버튼5"/>

</GridLayout>

 

특정 뷰 크기 확장: layout_gravity

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:orientation="horizontal">

    <Button android:text="버튼1"/>
    <Button android:text="이렇게 버튼 하나가 길어지면?"/>
    <Button android:text="버튼3"/>
    <Button android:text="버튼4"/>
    <Button android:text="버튼5"
        android:layout_gravity="fill_horizontal"/>
    <Button android:text="버튼6"/>

</GridLayout>

 

혹은 버튼이 기니까, 거기에 버튼5와 버튼 6을 넣을 수도 있습니다. 

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:orientation="horizontal">

    <Button android:text="버튼1"/>
    <Button android:text="이렇게 버튼 하나가 길어지면?"/>
    <Button android:text="버튼3"/>
    <Button android:text="버튼4"/>
    <Button android:text="버튼5"/>
    <Button android:text="버튼6"        
        android:layout_row="1"
        android:layout_column="1"
        android:layout_gravity="right"/>

</GridLayout>

 

병합하기: layout_rowSpan, layout_columnSpan

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:orientation="horizontal">

    <Button android:text="버튼1"
        android:layout_rowSpan="2"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"/>
    <Button android:text="버튼2"/>
    <Button android:text="버튼3"/>
    <Button android:text="버튼4"/>
    <Button android:text="버튼5"/>
    <Button android:text="버튼6"/>

</GridLayout>


계층 구조 배치: ContraintLayout

 

ConstraintLayout을 사용하려면 build.gradle 파일에 implementation 설정이 필요합니다.

보통 자동으로 설정되어 있습니다. 

build.gradle에 이미 설정이 잘 되어 있습니다.

레이아웃 편집기

ConstraintLayout은 레이아웃 편집기를 제공합니다. 

레이아웃 편집기에서는  팔레트에서 뷰를 드래그 앤 드롭해서 화면을 구성합니다. 

 

우리는 연습삼아서 카톡 화면을 따라해보겠습니다.

우선 화면 구성을 대충 한번 쓱 봐주세요!

레이아웃 편집기

 

이미지 추가

그 다음에 미리 준비한 카톡 이미지를 선택

그럼 이렇게 이미지가 불러와 집니다. 근데 너무 크네요. 

 

이제 위치를 설정해 줍니다. 왼쪽과 위 간격을 16으로 설정하겠습니다.

 

이제 카톡 이미지 옆에 텍스트를 넣어볼께요.

 

텍스트뷰에 카카오톡이라고 내용을 채워볼께요. 속성창에서 내용을 써주세요.

 

그 다음 그림과의 간격을 조정해 볼께요.

이게 약간 PPT랑 비슷한데, 뷰에 마우스 커서를 가져다 대면 상하좌우로 동그라미가 생겨요. 

텍스트뷰의 왼쪽 동그라미랑 카카오톡 이미지의 오른쪽 동그라미를 연결해서 구속 조건을 걸어 줍니다. 

 

같은 방법으로 그림과 텍스트뷰 상단을 0으로 맞춰 줄께요.

 

이제는 텍스트 뷰를 하나 더 꺼내서 내용을 "[기기 로그인 알림]"로 하고,

그림과의 왼쪽 간격은 16으로, 아래 간격은 0으로 세팅해 봅시다.

 

끝으로 날짜를 하나 넣어서 오른쪽과 상단 간격을 16으로 둡시다.

 

자 그럼 짜잔~! 뭔가 카카오톡 같지 않나여? 🤣

그럴싸함

 

그럼 이렇게 만든 것이 코드로 잘 작성됐나 이걸 코드 모드로 가서 한번 볼께요.

맨 왼쪽을 눌러주세요
캬 잘 작성됐다~

 

'Android' 카테고리의 다른 글

뷰를 이용한 화면 구성  (0) 2025.06.13
코틀린 유용한 기법  (0) 2025.06.09
코틀린 객체 지향 프로그래밍  (0) 2025.06.04
고틀린  (0) 2025.06.01
안드로이드 앱 기본 구조  (0) 2025.05.30