
ConstraintLayout match_constraint는 0dp를 실전에서 제대로 쓰기 위해 꼭 이해해야 하는 개념입니다. 4편에서 0dp가 크기 0이 아니라 제약 기준 크기 계산이라는 점을 봤다면, 이번 편은 그 계산이 언제 성공하고 언제 실패하는지 더 구체적으로 봅니다.
핵심은 단순합니다. match_constraint는 양쪽 제약 사이의 사용 가능한 공간을 채우고, 필요하면 min/max로 크기를 제한합니다.

ConstraintLayout match_constraint는 0dp의 실제 의미다
ConstraintLayout에서 width나 height를 0dp로 쓰면 대부분 MATCH_CONSTRAINT로 동작합니다. 즉, View가 스스로 내용 크기를 정하는 wrap_content도 아니고, 개발자가 고정값을 주는 fixed dp도 아닙니다. 제약 관계를 보고 사용할 수 있는 크기를 계산합니다.
- wrap_content: 내용이 크기 기준
- fixed dp: 지정한 값이 크기 기준
- 0dp / match_constraint: 제약 사이 사용 가능한 공간이 크기 기준
그래서 match_constraint를 볼 때는 XML 한 줄만 보면 안 됩니다. 반드시 같은 방향의 제약을 함께 봐야 합니다. width=0dp라면 start와 end를 보고, height=0dp라면 top과 bottom을 봅니다.
parent 양끝 사이를 채우는 가장 작은 예
가장 단순한 성공 예시는 View의 width를 0dp로 두고 start와 end를 모두 parent에 연결하는 것입니다. 이때 View는 parent 안에서 사용할 수 있는 가로 공간을 채웁니다.
<TextView
android:id="@+id/bannerText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Full width banner"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
이 구조는 match_parent처럼 보일 수 있습니다. 하지만 ConstraintLayout 안에서는 parent 양쪽 제약과 0dp 조합으로 읽는 편이 더 자연스럽습니다. 나중에 margin, bias, min/max, ratio와도 이어지기 때문입니다.
아이콘 옆 TextView는 match_constraint가 잘 맞는다
실무에서 가장 자주 보는 패턴은 아이콘 옆의 긴 텍스트입니다. 아이콘은 48dp처럼 고정 크기이고, 텍스트는 아이콘 오른쪽부터 parent 끝까지 남은 폭을 사용해야 합니다.
<ImageView
android:id="@+id/iconImage"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/titleText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Long title can use remaining space"
app:layout_constraintStart_toEndOf="@id/iconImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/iconImage" />
titleText는 iconImage의 end와 parent의 end 사이를 사용합니다. marginStart 16dp가 있으므로 실제로는 아이콘과의 간격을 제외한 남은 공간을 씁니다. 긴 제목이 parent 밖으로 밀리는 문제를 줄이는 데 좋은 구조입니다.
- 왼쪽 View: 고정 크기
- 오른쪽 TextView: width=0dp
- 오른쪽 TextView의 start: 왼쪽 View의 end
- 오른쪽 TextView의 end: parent end
버튼 사이 중간 영역도 같은 원리다
양쪽에 고정 폭 버튼이 있고 가운데 입력 영역만 늘어나야 하는 화면도 같은 원리로 만들 수 있습니다. 가운데 View를 0dp로 두고, start와 end를 양쪽 버튼에 연결합니다.
<Button
android:id="@+id/cancelButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="Cancel"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/inputText"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
app:layout_constraintStart_toEndOf="@id/cancelButton"
app:layout_constraintEnd_toStartOf="@id/okButton"
app:layout_constraintTop_toTopOf="@id/cancelButton" />
<Button
android:id="@+id/okButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="OK"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
이 예제에서 inputText는 parent 전체가 아니라 cancelButton과 okButton 사이의 공간만 사용합니다. match_constraint는 항상 화면 전체를 채우는 속성이 아니라, 연결된 제약 사이의 공간을 쓰는 속성입니다.
실패 조건은 제약 누락에서 시작한다
match_constraint가 이상하게 보일 때 가장 먼저 볼 것은 제약 누락입니다. width=0dp라면 가로 방향 끝점이 필요합니다. start만 있고 end가 없으면 사용할 수 있는 가로 공간의 끝을 알기 어렵습니다.
<!-- 실패하기 쉬운 예: width=0dp인데 end 제약이 없다 -->
<TextView
android:id="@+id/titleText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
세로도 같습니다. height=0dp를 쓰려면 top과 bottom을 함께 확인해야 합니다. 가로 문제를 세로 속성에서 찾거나, 세로 문제를 가로 속성에서 찾으면 디버깅 시간이 길어집니다.
- width=0dp: start와 end를 먼저 확인
- height=0dp: top과 bottom을 먼저 확인
- 기준 View가 GONE이 될 수 있으면 goneMargin도 함께 확인
- margin이 너무 커서 남은 공간이 없어지는지도 확인
minWidth와 maxWidth로 남은 공간을 제한한다
match_constraint는 사용 가능한 공간을 채우지만, 실무에서는 너무 작아지거나 너무 커지는 것을 막아야 할 때가 있습니다. 이때 minWidth와 maxWidth 계열 속성을 함께 쓸 수 있습니다.
<TextView
android:id="@+id/titleText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minWidth="120dp"
app:layout_constraintWidth_max="240dp"
android:text="Title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
minWidth는 최소 폭을 보장하고, maxWidth는 최대 폭을 제한합니다. 다만 이것만으로 모든 긴 텍스트 문제가 해결되지는 않습니다. TextView라면 줄바꿈, maxLines, ellipsize 같은 텍스트 표시 정책도 함께 정해야 합니다.
- 너무 작아지면 버튼이나 텍스트가 읽기 어려운 경우: minWidth
- 태블릿에서 View가 너무 넓어지는 경우: maxWidth
- 긴 텍스트 처리: maxLines, ellipsize, 줄바꿈 정책도 함께 검토
percent와 ratio는 여기서 이어진다
공식 레퍼런스는 match_constraint에 percent와 dimensionRatio 같은 추가 조건도 설명합니다. 다만 이 편에서 모두 깊게 다루면 핵심이 흐려집니다. percent 크기는 9편, dimensionRatio는 8편에서 이미지 중심으로 따로 정리합니다.
이번 편에서 기억할 것은 하나입니다. percent와 ratio도 결국 제약 기반 크기 계산 위에 조건을 더하는 방식입니다. 그래서 0dp와 양쪽 제약을 먼저 이해해두면 후속 속성이 훨씬 쉬워집니다.
실무 판단 기준
- 한 방향으로만 제약이 있으면 match_constraint부터 의심한다
- 양쪽 제약이 있다면 남은 공간 계산이 가능한지 본다
- 고정 View 옆 긴 텍스트는 0dp가 유리한 경우가 많다
- 너무 작거나 커지는 문제는 min/max로 제한한다
- 텍스트 overflow는 크기 계산과 텍스트 표시 정책을 함께 본다
match_constraint를 잘 쓰면 ConstraintLayout XML이 오히려 읽기 쉬워집니다. “이 View는 남은 공간을 쓰는 역할”이라고 명확해지기 때문입니다. 반대로 아무 View에나 0dp를 넣으면 제약 누락과 크기 제한 문제를 동시에 만들 수 있습니다.
정리
ConstraintLayout match_constraint는 0dp의 실전 의미입니다. 사용 가능한 공간을 채우되, 그 공간은 연결된 제약과 margin에 의해 정해집니다. 성공 조건은 양쪽 제약이고, 대표 실패 조건은 제약 누락입니다.
- 0dp는 match_constraint로 읽는다
- width=0dp는 가로 양쪽 제약을 확인한다
- height=0dp는 세로 양쪽 제약을 확인한다
- min/max로 계산된 크기를 제한할 수 있다
- percent와 ratio는 후속 편에서 더 깊게 다룬다
다음 편에서는 bias를 다룹니다. 양쪽 제약이 있는 View를 가운데가 아니라 왼쪽이나 오른쪽, 위쪽이나 아래쪽으로 어떻게 밀 수 있는지 정리하겠습니다.
아래에는 이 편보다 앞에서 다룬 글만 모았습니다. 아직 뒤 편은 발행 전이므로 링크하지 않습니다.
공식 기준은 Android Developers ConstraintLayout 가이드와 AndroidX ConstraintLayout 레퍼런스를 확인했습니다.