|

Android ConstraintLayout 완전 정리 (1) – ConstraintLayout 기본 사용법: LinearLayout과 다른 제약 기반 배치 이해하기

Android ConstraintLayout 완전 정리 (1) – ConstraintLayout 기본 사용법: LinearLayout과 다른 제약 기반 배치 이해하기
ConstraintLayout은 XML 코드와 실제 배치 결과를 같이 볼 때 이해가 빨라집니다.

ConstraintLayout 기본 사용법은 View를 화면에 “놓는 법”보다 View가 어디에 묶이는지 보는 데서 시작합니다. LinearLayout처럼 순서대로 쌓는 방식이 아니라, parent나 다른 View와의 제약 관계로 위치를 정합니다.

이 글에서는 가장 작은 XML 예시와 실제 배치 이미지를 함께 보면서 ConstraintLayout에서 View 위치가 결정되는 기준을 잡습니다.

ConstraintLayout 기본 사용법 제약 없음과 제약 있음 비교 이미지
ConstraintLayout에서는 View마다 가로와 세로 방향 제약을 갖춰야 위치를 예측할 수 있습니다.

ConstraintLayout 기본 사용법은 제약 관계를 읽는 것부터 시작한다

ConstraintLayout에서 중요한 단어는 세 가지입니다. parent, child view, 그리고 constraint입니다. parent는 전체 레이아웃이고, child view는 그 안에 놓이는 TextView나 Button 같은 View입니다. constraint는 child view의 한쪽 기준선을 parent나 다른 View에 연결하는 규칙입니다.

  • parent: ConstraintLayout 자체
  • child view: TextView, Button, ImageView 같은 내부 View
  • constraint: View의 start, end, top, bottom 등을 어떤 기준에 연결할지 정하는 속성

처음에는 constraint를 “좌표 지정”으로 생각하기 쉽습니다. 하지만 ConstraintLayout은 x, y 좌표를 직접 쓰는 방식이 아닙니다. View의 edge를 다른 기준 edge에 연결하고, 그 관계를 바탕으로 최종 위치를 계산합니다.

  • 위치를 직접 찍는 생각: 이 View는 x=24, y=32에 둔다
  • 제약으로 읽는 생각: 이 View의 start를 parent start에서 24dp 떨어뜨린다
  • 실무에서 중요한 생각: 기준 View가 움직이면 연결된 View도 같이 움직인다

제약이 없는 View는 실제 실행에서 믿을 수 없다

Android Studio Preview에서는 View가 화면 어딘가에 놓인 것처럼 보일 수 있습니다. 하지만 공식 문서 기준으로 제약이 없는 View는 실행 시 [0,0], 즉 왼쪽 위에 그려질 수 있습니다. 그래서 Preview에서 보이는 위치만 믿으면 안 됩니다.

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/titleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello ConstraintLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

위 예시는 XML 문법만 보면 틀리지 않습니다. 하지만 titleText에는 가로 방향 제약도 없고 세로 방향 제약도 없습니다. ConstraintLayout 안에서 위치를 안정적으로 정하려면 최소한 가로 기준 하나와 세로 기준 하나가 필요합니다.

여기서 “최소한 하나씩”이라는 말은 가로 방향과 세로 방향을 따로 봐야 한다는 뜻입니다. start만 있으면 가로 위치는 어느 정도 정해지지만 세로 위치는 정해지지 않습니다. top만 있으면 세로 위치는 정해지지만 가로 위치는 정해지지 않습니다.

  • 가로 방향 기준: start 또는 end 중 하나 이상
  • 세로 방향 기준: top 또는 bottom 중 하나 이상
  • 텍스트끼리 줄 기준을 맞출 때는 baseline 제약도 세로 기준 역할을 할 수 있음
ConstraintLayout 기본 사용법 parent start top 제약 예시
parent 기준 제약은 가장 작은 ConstraintLayout 예제입니다.

가장 작은 정상 예제: parent start와 top에 붙이기

가장 작은 정상 예제는 View의 start를 parent의 start에, top을 parent의 top에 연결하는 것입니다. 이렇게 하면 View가 어느 기준에 붙는지 명확해집니다.

<TextView
    android:id="@+id/titleText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello ConstraintLayout"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

여기서 start는 왼쪽이라고만 외우기보다 “문자 방향 기준의 시작점”으로 이해하는 편이 좋습니다. 한국어와 영어처럼 왼쪽에서 오른쪽으로 읽는 환경에서는 start가 보통 왼쪽이지만, RTL 언어 환경에서는 달라질 수 있습니다.

ConstraintLayout 기본 사용법 sibling 기준 View 배치 예시
ConstraintLayout은 View끼리 서로 기준이 될 수 있습니다.

이 예제는 단순하지만, 이후 속성 대부분의 출발점입니다. margin을 붙이면 기준선에서 떨어지고, end 제약을 추가하면 가운데 정렬이나 bias 조절이 가능해집니다. width를 0dp로 바꾸면 두 제약 사이의 남은 공간 계산도 시작됩니다.


다른 View도 기준이 될 수 있다

ConstraintLayout은 parent만 기준으로 삼지 않습니다. 한 View를 다른 View 옆에 붙일 수도 있습니다. 이 방식이 익숙해지면 카드 UI, 프로필 UI, 입력 폼을 훨씬 유연하게 만들 수 있습니다.

<TextView
    android:id="@+id/nameText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Name"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/valueText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="BS Code Lab"
    app:layout_constraintStart_toEndOf="@id/nameText"
    app:layout_constraintTop_toTopOf="@id/nameText" />

valueText의 start는 nameText의 end에 연결됩니다. 즉 valueText는 parent의 왼쪽이 아니라 nameText의 오른쪽을 기준으로 움직입니다.

이 관계는 label/value UI에서 자주 씁니다. label의 텍스트가 짧든 길든 value는 label 뒤쪽에 붙습니다. 다만 label 길이가 크게 변하는 화면에서는 13편에서 다룰 Barrier가 더 적합할 수 있습니다.


작은 카드 UI에 적용하면 구조가 보인다

실제 화면에서는 parent 기준과 sibling 기준을 섞습니다. 예를 들어 프로필 카드에서 이미지는 parent start/top에 붙이고, 제목은 이미지의 end에 붙입니다. 버튼은 이미지나 텍스트 아래쪽 기준에 맞출 수 있습니다.

<ImageView
    android:id="@+id/profileImage"
    android:layout_width="56dp"
    android:layout_height="56dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/titleText"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toEndOf="@id/profileImage"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="@id/profileImage" />

<Button
    android:id="@+id/actionButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toBottomOf="@id/titleText" />

이 예제에서 profileImage는 parent 기준입니다. titleText는 profileImage와 parent를 동시에 기준으로 삼습니다. actionButton은 parent의 end와 titleText의 bottom을 기준으로 위치를 정합니다.

ConstraintLayout 기본 사용법 카드 UI 제약 관계 예시
실제 UI에서는 parent 기준과 sibling 기준 제약을 함께 사용합니다.

처음부터 복잡한 화면을 한 번에 만들려고 하면 어렵습니다. 기준 View를 하나 정하고, 그 View에 붙는 View를 하나씩 늘리는 방식이 더 안전합니다.


LinearLayout과 다르게 봐야 하는 지점

LinearLayout은 자식 View를 방향에 따라 순서대로 놓습니다. ConstraintLayout은 순서보다 관계가 중요합니다. XML에서 아래에 쓰인 View라도 제약 관계에 따라 위쪽에 배치될 수 있습니다.

  • LinearLayout: 순서와 방향이 중심
  • RelativeLayout: 상대 배치가 가능하지만 복잡해지면 읽기 어려움
  • ConstraintLayout: 제약 관계와 크기 계산을 함께 다룸

입문 단계에서는 “ConstraintLayout이 더 좋다”처럼 외우지 않는 편이 좋습니다. 단순한 세로 목록은 LinearLayout이 더 읽기 쉬울 수 있습니다. 반대로 여러 View가 서로의 위치와 크기에 영향을 주는 화면은 ConstraintLayout이 더 자연스럽습니다.

  • 단순 목록: LinearLayout이나 RecyclerView가 더 자연스러울 수 있음
  • 카드 안의 이미지/텍스트/버튼 조합: ConstraintLayout이 읽기 쉬운 경우가 많음
  • 중첩 LinearLayout이 깊어지는 화면: ConstraintLayout로 평평하게 만들 수 있음

XML 기반 UI와 Compose UI를 어디서부터 배울지 고민 중이라면 Jetpack Compose와 XML 차이 글을 함께 보면 학습 순서를 잡는 데 도움이 됩니다.


정리

ConstraintLayout 기본 사용법은 많은 속성을 외우는 것이 아니라, View가 어떤 기준에 연결되는지 읽는 것입니다. 처음에는 start/top처럼 단순한 제약부터 잡고, 그 다음 sibling 기준 배치와 크기 계산으로 넘어가면 훨씬 덜 헷갈립니다.

  • View마다 가로/세로 기준을 따로 확인한다
  • parent 기준인지 sibling 기준인지 먼저 읽는다
  • Preview 위치보다 실제 constraint 속성을 신뢰한다
  • 복잡한 화면은 기준 View를 정하고 한 View씩 붙인다

다음 편에서는 start, end, top, bottom 제약을 방향별로 나누어 보고, parent와 sibling 기준 배치가 실제 화면에서 어떻게 달라지는지 정리합니다. 아직 다음 편은 발행 전이므로 링크는 발행 후 추가합니다.

공식 기준은 Android Developers ConstraintLayout 가이드AndroidX ConstraintLayout 레퍼런스를 확인했습니다.

함께보면 좋은 글