
ConstraintLayout bias는 양쪽 제약이 있는 View를 정확히 가운데가 아니라 조금 왼쪽, 오른쪽, 위쪽, 아래쪽으로 밀고 싶을 때 쓰는 속성입니다. 5편에서 0dp와 양쪽 제약을 봤다면, 이번 편은 그 양쪽 제약 사이에서 위치를 조절하는 단계입니다.
핵심은 bias는 제약 없이 View를 움직이는 속성이 아니라, 서로 반대되는 두 제약 사이의 위치 비율이라는 점입니다.

ConstraintLayout bias는 양쪽 제약이 있을 때 의미가 있다
bias를 이해하려면 먼저 양쪽 제약을 확인해야 합니다. 가로 bias는 start와 end 제약이 모두 있을 때 의미가 있습니다. 세로 bias는 top과 bottom 제약이 모두 있을 때 의미가 있습니다.
- horizontalBias: start와 end 제약 사이의 가로 위치
- verticalBias: top과 bottom 제약 사이의 세로 위치
- 기본값: 보통 0.5, 즉 가운데
- 0.0에 가까울수록 start/top 쪽
- 1.0에 가까울수록 end/bottom 쪽
공식 레퍼런스도 서로 반대되는 제약을 만났을 때 기본은 가운데이며, bias 속성으로 어느 한쪽을 더 선호하도록 조절할 수 있다고 설명합니다.
horizontalBias로 좌우 위치 조절하기
가장 자주 쓰는 예는 horizontalBias입니다. Button을 parent start와 parent end에 모두 연결하면 기본적으로 가운데에 놓입니다. 여기에 horizontalBias를 0.25로 주면 가운데보다 start 쪽에 가까워집니다.
<Button
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Action"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.25" />
0.25라는 값은 왼쪽으로 25dp 이동한다는 뜻이 아닙니다. 양쪽 제약 사이에서 start 쪽을 더 선호한다는 뜻입니다. 화면 폭이 바뀌면 실제 픽셀 위치도 달라집니다.
- 0.0: start 쪽에 가장 가까움
- 0.5: 가운데
- 1.0: end 쪽에 가장 가까움
- 0.25: 가운데보다 start 쪽
- 0.75: 가운데보다 end 쪽
verticalBias로 위아래 위치 조절하기
verticalBias도 원리는 같습니다. View의 top과 bottom을 모두 parent에 연결한 뒤 verticalBias를 조절하면, View가 위쪽이나 아래쪽으로 치우칩니다.
<TextView
android:id="@+id/messageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty state"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.25" />
빈 상태 화면에서 문구를 화면 정중앙보다 조금 위에 두고 싶을 때 이런 방식이 자연스럽습니다. absolute y 좌표를 쓰는 것이 아니라, parent 위아래 제약 사이에서 비율로 위치를 정합니다.
margin이 있으면 bias 범위도 달라진다
bias는 parent 전체 폭이나 높이만 보고 계산되는 것이 아닙니다. 양쪽 제약과 margin이 함께 있으면, margin을 뺀 남은 공간 안에서 위치가 조절됩니다.
<Button
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:text="Action"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5" />
양쪽 margin이 같으면 bias 0.5는 여전히 가운데처럼 보입니다. 하지만 실제 이동 가능한 범위는 parent 전체가 아니라 margin을 제외한 공간입니다. margin이 다르면 같은 bias 값이라도 눈에 보이는 위치가 달라질 수 있습니다.
bias가 안 먹는 이유는 대부분 제약이 부족해서다
bias가 안 먹는다고 느껴질 때는 속성 이름부터 의심하기보다 제약부터 봐야 합니다. horizontalBias를 썼는데 end 제약이 없으면 좌우로 나눌 두 기준점이 없습니다. verticalBias도 top 또는 bottom 중 하나가 빠지면 의미가 약해집니다.
<!-- 좋지 않은 예: horizontalBias가 있지만 end 제약이 없다 -->
<Button
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Action"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.75" />
- horizontalBias가 안 먹는다: start와 end가 모두 있는지 확인
- verticalBias가 안 먹는다: top과 bottom이 모두 있는지 확인
- 0dp와 함께 쓴다: 위치 조절인지 크기 계산인지 나눠서 확인
- margin이 있다: bias가 적용되는 실제 범위를 다시 확인
실무 카드 UI에서 bias를 쓰는 경우
실무에서는 모든 View를 정확히 가운데에 두지 않습니다. 카드 안의 액션 버튼을 약간 오른쪽에 두거나, 빈 상태 문구를 화면 중앙보다 조금 위에 두는 식의 배치가 필요할 수 있습니다. 이럴 때 bias가 유용합니다.

물론 bias를 남용하면 XML을 읽기 어려워집니다. 단순히 16dp 오른쪽으로 띄우고 싶은 문제라면 margin이 더 분명할 수 있습니다. 반대로 화면 크기가 달라져도 비율상 비슷한 위치를 유지하고 싶다면 bias가 더 자연스럽습니다.
- 고정 간격이 필요하다: margin
- 양쪽 제약 사이 위치 비율이 필요하다: bias
- View 크기 자체가 남은 공간을 써야 한다: 0dp / match_constraint
- 여러 View 묶음의 위치 조절은 chain 편에서 다시 다룸
0dp와 bias를 함께 볼 때의 기준
0dp와 bias는 같이 등장할 수 있지만 역할이 다릅니다. 0dp는 View의 크기를 제약 사이에서 계산합니다. bias는 View의 위치를 제약 사이에서 조절합니다.
- width=0dp: 가로 크기 계산
- layout_constraintHorizontal_bias: 가로 위치 조절
- height=0dp: 세로 크기 계산
- layout_constraintVertical_bias: 세로 위치 조절
그래서 어떤 문제가 생겼는지 먼저 나눠야 합니다. View 폭이 이상하면 0dp와 제약을 봅니다. View 위치가 가운데에서 벗어나지 않으면 bias와 반대 제약을 봅니다.
정리
ConstraintLayout bias는 양쪽 제약 사이에서 View 위치를 비율로 조절하는 속성입니다. 기본은 0.5이고, 0.0에 가까우면 start/top 쪽, 1.0에 가까우면 end/bottom 쪽으로 움직입니다.
- bias는 양쪽 제약이 있을 때 의미가 있다
- horizontalBias는 좌우 위치 조절
- verticalBias는 위아래 위치 조절
- margin은 bias가 움직일 수 있는 범위에 영향을 준다
- bias가 안 먹으면 반대쪽 제약 누락부터 확인한다
다음 편에서는 baseline 정렬을 다룹니다. TextView의 박스 위쪽이 아니라 글자 기준선을 맞춰야 하는 상황을 label/value UI로 정리하겠습니다.
아래에는 이 편보다 앞에서 다룬 글만 모았습니다. 아직 뒤 편은 발행 전이므로 링크하지 않습니다.
공식 기준은 Android Developers ConstraintLayout 가이드와 AndroidX ConstraintLayout 레퍼런스를 확인했습니다.
Android ConstraintLayout 완전 정리 이전 글 모음
Android ConstraintLayout 완전 정리 (1) – ConstraintLayout 기본 사용법: LinearLayout과 다른 제약 기반 배치 이해하기
Android ConstraintLayout 완전 정리 (3) – ConstraintLayout goneMargin과 margin 차이: View.GONE일 때 간격이 바뀌는 이유
Android ConstraintLayout 완전 정리 (5) – ConstraintLayout match_constraint 완전 정리: 0dp가 남은 공간을 채우는 원리