|

Android ConstraintLayout 완전 정리 (20) – ConstraintLayout 실전 예제: 프로필 카드, 상품 카드, 채팅 입력창 만들기

Android ConstraintLayout 완전 정리 (20) – ConstraintLayout 실전 예제: 프로필 카드, 상품 카드, 채팅 입력창 만들기
프로필 카드, 상품 카드, 채팅 입력창, 반응형 상세 화면을 속성 조합 관점으로 정리합니다.

ConstraintLayout 실전 예제를 볼 때 중요한 것은 XML을 길게 외우는 것이 아닙니다. 화면마다 어떤 기준에 붙이고, 어떤 View를 0dp로 계산하고, 어떤 helper를 쓸지 판단하는 순서입니다.

이번 글은 Android ConstraintLayout 완전 정리 시리즈의 마지막 편입니다. 앞에서 다룬 제약, 0dp, bias, ratio, chain, Guideline, Barrier, Flow를 실제 UI 조합 기준으로 다시 묶겠습니다.


ConstraintLayout 실전 예제에서 먼저 볼 것

ConstraintLayout 실전 예제별 핵심 속성 조합 이미지
실전 예제는 속성을 하나씩 외우는 것이 아니라 화면마다 필요한 조합을 고르는 과정입니다.

실전 화면은 속성 하나로 해결되지 않습니다. 프로필 카드는 sibling 기준과 0dp 텍스트 영역이 중요하고, 상품 카드는 이미지 비율과 남은 공간 계산이 중요합니다. 채팅 입력창은 가운데 입력 영역을 어떻게 늘릴지가 핵심이고, 상세 화면은 화면 폭에 따라 기준선을 다르게 잡아야 합니다.

  • 프로필 카드: 이미지, 이름, 설명, 버튼이 서로 어떤 기준을 공유하고 어느 영역을 0dp로 둘지 본다.
  • 상품 카드: 썸네일 비율과 텍스트 영역의 0dp 계산을 함께 본다.
  • 채팅 입력창: 좌우 버튼은 고정하고 입력창만 남은 공간을 채우게 한다.
  • 반응형 상세 화면: 모바일과 태블릿에서 같은 기준을 쓸지, Guideline으로 나눌지 결정한다.

예제 1: 프로필 카드 만들기

프로필 카드는 ConstraintLayout을 처음 실전에서 쓰기 좋은 예제입니다. 아바타는 parent 기준으로 붙이고, 이름과 설명은 아바타의 end 기준으로 배치합니다. 텍스트 영역은 0dp로 두어 남은 폭을 쓰게 만들고, 버튼은 설명 아래나 카드 오른쪽 기준에 맞출 수 있습니다.

ConstraintLayout 실전 예제 프로필 카드 배치 이미지
프로필 카드는 이미지와 텍스트, 버튼이 서로 다른 기준을 공유하는 대표 예제입니다.

아래 XML은 전체 스타일을 모두 담은 코드가 아니라 핵심 constraint만 남긴 축약 예시입니다. 실제 프로젝트에서는 margin, textAppearance, contentDescription, 이미지 리소스를 화면 정책에 맞게 추가해야 합니다.

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="20dp">

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

    <TextView
        android:id="@+id/nameText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="BS Code"
        android:layout_marginStart="16dp"
        app:layout_constraintStart_toEndOf="@id/avatar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/avatar" />

    <TextView
        android:id="@+id/descText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        app:layout_constraintStart_toStartOf="@id/nameText"
        app:layout_constraintEnd_toEndOf="@id/nameText"
        app:layout_constraintTop_toBottomOf="@id/nameText" />

    <Button
        android:id="@+id/followButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/descText"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

여기서 핵심은 TextView의 width를 0dp로 둔 부분입니다. 이름과 설명은 아바타 오른쪽에서 parent end까지 남은 공간을 씁니다. 긴 이름이나 설명이 들어와도 어느 영역 안에서 줄바꿈될지 예측하기 쉽습니다.


예제 2: 상품 카드 만들기

상품 카드는 이미지 비율이 중요합니다. 썸네일은 카드 폭에 맞춰 16:9를 유지하고, 그 아래 텍스트와 가격은 내용에 맞춰 배치하는 식으로 나눌 수 있습니다.

ConstraintLayout 실전 예제 상품 카드 dimensionRatio 이미지
상품 카드는 이미지 비율과 텍스트 영역의 남은 폭 계산을 함께 봐야 합니다.

이 예제도 전체 카드 XML이 아니라 이미지, 제목, 가격의 핵심 제약만 보여줍니다. 실제 카드에서는 padding, margin, 배경, 클릭 영역, 접근성 속성을 함께 설계해야 합니다.

<ImageView
    android:id="@+id/productImage"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="centerCrop"
    app:layout_constraintDimensionRatio="16:9"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/productTitle"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="@id/productImage"
    app:layout_constraintEnd_toEndOf="@id/productImage"
    app:layout_constraintTop_toBottomOf="@id/productImage" />

<TextView
    android:id="@+id/priceText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="@id/productTitle"
    app:layout_constraintTop_toBottomOf="@id/productTitle" />

dimensionRatio는 단독으로 비율을 해결해 주는 속성이 아닙니다. width와 height, 그리고 양쪽 제약이 함께 맞아야 합니다. 8편에서 다룬 ratio 규칙과 4~5편의 0dp 규칙이 여기서 같이 쓰입니다.


예제 3: 채팅 입력창 만들기

채팅 입력창은 실무에서 자주 쓰는 패턴입니다. 왼쪽 추가 버튼과 오른쪽 전송 버튼은 고정 크기로 두고, 가운데 EditText만 남은 공간을 채우게 만들면 화면 폭이 바뀌어도 구조가 안정적입니다.

ConstraintLayout 실전 예제 채팅 입력창 0dp 배치 이미지
채팅 입력창은 좌우 버튼을 고정하고 가운데 입력 영역을 0dp로 두는 패턴이 잘 맞습니다.

여기서 0dp는 입력창의 글자를 0으로 만든다는 뜻이 아니라, 좌우 버튼 사이의 남은 폭을 constraint로 계산하겠다는 뜻입니다.

<ImageButton
    android:id="@+id/addButton"
    android:layout_width="48dp"
    android:layout_height="48dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintBottom_toBottomOf="parent" />

<EditText
    android:id="@+id/messageInput"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:minHeight="48dp"
    app:layout_constraintStart_toEndOf="@id/addButton"
    app:layout_constraintEnd_toStartOf="@id/sendButton"
    app:layout_constraintBottom_toBottomOf="@id/addButton" />

<ImageButton
    android:id="@+id/sendButton"
    android:layout_width="48dp"
    android:layout_height="48dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent" />

이 예제에서는 chain을 반드시 만들 필요는 없습니다. 핵심은 가운데 입력창의 start와 end를 양쪽 버튼 사이에 연결하고 width를 0dp로 두는 것입니다. 버튼 수가 늘어나거나 여러 액션을 균등 배치해야 할 때 chain을 검토하면 됩니다.


예제 4: 반응형 상세 화면 만들기

모바일에서는 이미지, 제목, 버튼을 위에서 아래로 배치하는 흐름이 자연스럽습니다. 하지만 태블릿이나 가로 화면에서는 이미지와 정보 영역을 나누는 편이 읽기 좋을 수 있습니다.

ConstraintLayout 실전 예제 반응형 상세 화면 Guideline 이미지
상세 화면은 화면 폭이 넓어질 때 Guideline으로 이미지 영역과 정보 영역을 나누기 좋습니다.

실제 앱에서는 화면 크기별 layout 리소스나 별도 화면 구성을 함께 검토해야 합니다. 여기서는 넓은 화면 XML을 설계할 때 Guideline을 기준선으로 쓰는 패턴만 따로 떼어 보겠습니다.

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/contentGuideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.40" />

<ImageView
    android:id="@+id/heroImage"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="4:3"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/contentGuideline"
    app:layout_constraintTop_toTopOf="parent" />

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

Guideline은 보이지 않는 기준선입니다. View처럼 화면에 그려지는 요소가 아니라 여러 View가 공유할 수 있는 기준입니다. 그래서 넓은 화면에서는 Guideline을 먼저 잡고 이미지와 텍스트 영역을 나누는 방식이 읽기 쉽습니다.


언제 Barrier와 Flow를 섞을까

실전 화면에서는 Guideline이나 0dp만으로 충분하지 않은 경우도 있습니다. 텍스트 길이가 달라져 다른 View가 겹친다면 Barrier를 검토할 수 있고, 개수가 비교적 고정된 태그나 옵션 chip을 여러 줄로 배치해야 한다면 Flow가 맞을 수 있습니다.

  • Barrier: 텍스트 길이가 달라지고, 그 아래나 옆 View가 가장 긴 요소를 기준으로 움직여야 할 때
  • Flow: 개수가 비교적 고정된 chip, 옵션, badge를 화면 폭에 맞춰 줄바꿈 배치할 때. 긴 목록은 RecyclerView로 분리한다.
  • Chain: 같은 줄의 버튼이나 탭을 균등하게 나누거나 묶어서 정렬할 때
  • Guideline: 여러 View가 같은 비율 기준선을 공유해야 할 때

다만 모든 helper를 한 화면에 넣는 것이 좋은 설계는 아닙니다. helper는 복잡도를 줄일 때만 써야 합니다. 설명하기 어려운 helper 조합이 많아지면, 오히려 레이아웃을 나누거나 목록 UI를 별도 컴포넌트로 분리하는 편이 더 읽기 쉬울 수 있습니다.


속성 선택 순서

ConstraintLayout 실전 예제 속성 선택 순서 이미지
실전에서는 속성을 외우기보다 기준, 크기, 비율, 묶음, 상태 순서로 고르는 편이 안정적입니다.

실전에서는 속성을 먼저 고르지 말고 질문을 먼저 던지는 편이 좋습니다. 기준은 무엇인지, 크기는 무엇으로 계산할지, 비율이 필요한지, 묶음이 필요한지, 상태 변화가 있는지를 차례로 보면 XML 구조가 덜 흔들립니다.

  • 기준: parent, sibling, Guideline 중 무엇을 기준으로 삼을지 정한다.
  • 크기: wrap_content, fixed dp, 0dp 중 어떤 계산 방식이 맞는지 정한다.
  • 비율: 이미지나 카드처럼 비율 유지가 필요한지 본다.
  • 묶음: chain, Flow, Barrier 같은 helper가 복잡도를 줄이는지 본다.
  • 상태: GONE, 긴 텍스트, 작은 화면에서도 깨지지 않는지 확인한다.

이 시리즈를 실무에서 다시 읽는 방법

ConstraintLayout을 처음부터 끝까지 한 번에 외우려고 하면 실전에 잘 남지 않습니다. 대신 문제가 생길 때 필요한 편으로 돌아가는 참고서처럼 쓰는 편이 좋습니다.

  • View 위치가 이상하면 2편 start/end/top/bottom과 19편 디버깅을 본다.
  • 0dp가 헷갈리면 4편과 5편을 다시 본다.
  • 가운데 정렬과 치우침은 6편 bias를 본다.
  • 이미지 비율은 8편 dimensionRatio를 본다.
  • 여러 버튼 배치는 10편과 11편 chain을 본다.
  • 반응형 기준선은 12편 Guideline과 13편 Barrier를 본다.
  • 상태별 화면은 18편을 본다.

한 번에 정리

  • ConstraintLayout 실전 예제는 속성 암기가 아니라 조합 판단이다.
  • 프로필 카드는 parent 기준과 sibling 기준을 함께 쓰기 좋다.
  • 상품 카드는 0dp와 dimensionRatio를 같이 봐야 한다.
  • 채팅 입력창은 가운데 입력 영역을 0dp로 두는 패턴이 안정적이다.
  • 넓은 화면 상세 UI는 Guideline으로 영역을 나누는 접근을 검토할 수 있다.
  • helper는 복잡도를 줄일 때만 쓰고, 모든 화면에 억지로 넣지 않는다.

ConstraintLayout을 잘 쓰는 기준은 속성을 많이 아는 것이 아니라, 화면마다 기준과 크기 계산 방식을 분명히 고르는 것입니다.


마무리

이 글로 Android ConstraintLayout 완전 정리 시리즈의 본문 흐름은 마무리됩니다. 기본 제약에서 시작해 0dp, bias, ratio, chain, Guideline, Barrier, Group, Flow, Layer, ConstraintSet, 상태별 레이아웃, 디버깅까지 연결했습니다.

공식 기준은 Android Developers ConstraintLayout 가이드, AndroidX ConstraintLayout API reference, AndroidX Guideline API reference, AndroidX Barrier API reference, AndroidX Flow API reference를 확인했습니다. 이후 이 시리즈는 필요하면 개별 편을 보강하거나, 별도 Compose 레이아웃 시리즈로 분리하는 편이 좋습니다.

Android ConstraintLayout 완전 정리 이전 글 모음

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

Android ConstraintLayout 완전 정리 (2) – ConstraintLayout start end top bottom 제약 정리: View를 원하는 위치에 붙이는 법

Android ConstraintLayout 완전 정리 (3) – ConstraintLayout goneMargin과 margin 차이: View.GONE일 때 간격이 바뀌는 이유

Android ConstraintLayout 완전 정리 (4) – ConstraintLayout width height 정리: wrap_content, 0dp, match_constraint 차이

Android ConstraintLayout 완전 정리 (5) – ConstraintLayout match_constraint 완전 정리: 0dp가 남은 공간을 채우는 원리

Android ConstraintLayout 완전 정리 (6) – ConstraintLayout bias 사용법: horizontalBias와 verticalBias로 위치 조절하기

Android ConstraintLayout 완전 정리 (7) – ConstraintLayout baseline 정렬: TextView 글자 기준선을 맞추는 방법

Android ConstraintLayout 완전 정리 (8) – ConstraintLayout dimensionRatio 사용법: 1:1, 16:9 이미지 비율 맞추기

Android ConstraintLayout 완전 정리 (9) – ConstraintLayout percent min max 크기 정리: 화면 크기에 맞게 View 조절하기

Android ConstraintLayout 완전 정리 (10) – ConstraintLayout chain 사용법: spread, spread_inside, packed 차이

Android ConstraintLayout 완전 정리 (11) – ConstraintLayout chain weight와 bias: 같은 폭, 다른 비율 배치 만들기

Android ConstraintLayout 완전 정리 (12) – ConstraintLayout Guideline 사용법: percent 기준선으로 화면 나누기

Android ConstraintLayout 완전 정리 (13) – ConstraintLayout Barrier 사용법: 텍스트 길이에 따라 동적 기준선 만들기

Android ConstraintLayout 완전 정리 (14) – ConstraintLayout Group과 Placeholder: 여러 View 숨기기와 위치 바꾸기

Android ConstraintLayout 완전 정리 (15) – ConstraintLayout Flow 사용법: Chip과 태그를 자동 줄바꿈 배치하기

Android ConstraintLayout 완전 정리 (16) – ConstraintLayout Layer 사용법: 여러 View를 함께 이동, 회전, 확대하기

Android ConstraintLayout 완전 정리 (17) – ConstraintSet 사용법: 코드로 ConstraintLayout 제약 바꾸기

Android ConstraintLayout 완전 정리 (18) – ConstraintLayout 상태별 레이아웃 설계: loading, empty, error 화면 만들기

Android ConstraintLayout 완전 정리 (19) – ConstraintLayout 오류 디버깅: View가 안 보이고 0dp가 깨지는 이유

함께보면 좋은 글