|

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

Android ConstraintLayout 완전 정리 (6) – ConstraintLayout bias 사용법: horizontalBias와 verticalBias로 위치 조절하기
ConstraintLayout은 XML 코드와 실제 배치 결과를 같이 볼 때 이해가 빨라집니다.

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

핵심은 bias는 제약 없이 View를 움직이는 속성이 아니라, 서로 반대되는 두 제약 사이의 위치 비율이라는 점입니다.

ConstraintLayout bias 0.0 0.5 1.0 위치 비교 이미지
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" />
ConstraintLayout horizontalBias 0.25 위치 조절 예시
horizontalBias는 양쪽 가로 제약 사이에서 View를 start나 end 쪽으로 이동시킵니다.

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" />
ConstraintLayout verticalBias 0.25 위치 조절 예시
verticalBias는 위아래 제약 사이에서 View를 top이나 bottom 쪽으로 이동시킵니다.

빈 상태 화면에서 문구를 화면 정중앙보다 조금 위에 두고 싶을 때 이런 방식이 자연스럽습니다. 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" />
ConstraintLayout bias margin 포함 이동 범위 예시
margin이 있으면 bias는 margin을 제외한 남은 제약 공간 안에서 적용됩니다.

양쪽 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" />
ConstraintLayout bias가 안 먹는 제약 누락 예시
bias는 서로 반대되는 두 제약이 있을 때 의미가 있습니다.
  • horizontalBias가 안 먹는다: start와 end가 모두 있는지 확인
  • verticalBias가 안 먹는다: top과 bottom이 모두 있는지 확인
  • 0dp와 함께 쓴다: 위치 조절인지 크기 계산인지 나눠서 확인
  • margin이 있다: bias가 적용되는 실제 범위를 다시 확인

실무 카드 UI에서 bias를 쓰는 경우

실무에서는 모든 View를 정확히 가운데에 두지 않습니다. 카드 안의 액션 버튼을 약간 오른쪽에 두거나, 빈 상태 문구를 화면 중앙보다 조금 위에 두는 식의 배치가 필요할 수 있습니다. 이럴 때 bias가 유용합니다.

ConstraintLayout bias 카드 UI 액션 버튼 위치 예시
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 레퍼런스를 확인했습니다.

함께보면 좋은 글