layered

2. 제약 레이아웃(ConstraintLayout) 본문

안드로이드/안드로이드 앱 프로그래밍

2. 제약 레이아웃(ConstraintLayout)

스윗푸들 2023. 4. 13. 09:21

개념


상속 관계

 

프로젝트를 처음 만들 때의 기본적인 레이아웃으로, 뷰의 크기와 위치를 결정할 때 제약 조건을 사용한다.

 

제약 조건이란?

뷰가 레이아웃 안의 다른 요소와 어떻게 연결되는지 알려주는 것(= 연결선)

 

간단하게 말하자면 다음과 같이 연결선을 통해 뷰의 상대적 위치를 정해 줘야 한다는 것이다.

그리고 위치라는 건 언제나 x와 y로 이루어지므로, 가로나 세로 중 하나라도 연결되지 않은 부분이 있다면 에러가 발생한다.

 

 

특성


연결점: 말그대로 뷰들을 연결해 주는 점으로 위 사진의 파란 동그라미이다

 

핸들: 뷰의 크기를 조정한다(꼭짓점의 파란 네모)

 

타깃: 제약 조건이 가리키는 뷰. 여기서는 벽(...?)

타깃이 될 수 있는 것은 여러 가지가 있다.

 

1) 같은 레이아웃 내 다른 뷰

2) 부모 레이아웃

3) 가이드라인

 

마진(margin): 연결점과 타깃의 거리

 

바이어스(Bias)


기본적으로 연결선이 양쪽에 있으면 가운데에 배치되어 마진이 고려되지 않는다. 하지만 임의로 위치를 조정하고 싶다면 바이어스를 사용하면 된다.

 

 

양쪽에 연결선을 만들게 되면 오른쪽의 레이아웃 부분에 바이어스가 만들어진다. 마찬가지로 세로로는 위로만 연결되어 있어서 바이어스가 없는 걸 볼 수 있다(세로 바이어스는 왼쪽에 생긴다).

 

위 사진은 내가 슬쩍 밀어서 49이긴 하지만 기본값은 50이다.  저걸 밀거나 끌어당기면서 마진을 조절하면 된다.

마진이 바뀌면 사진처럼 바이어스 밑의 Constraints 부분에 Horizontal Bias가 슬쩍 추가된다.

 

괄호 안의 값이 소수인 게 눈에 띄는데, 사실 바이어스는 화면을 비율로 나눈 후 위치를 결정하는 값이기 때문이다. 다만 디자인 화면에서는 %로 표시되는 것이다.

 

app:layout_constraintHorizontal_bias="0.498"

 

XML 코드에서는 이렇게 표시된다.

 

뷰 크기 조절하기


여러 가지 방법이 있다.

 

  1. 뷰의 핸들(꼭짓점)을 이용해 조정한다
  2. 속성 창에서 직접 설정한다
  3. 제약 조건이 표시된 그림을 이용한다

 

3번이 조금 특이한데, 일단 사진을 보자.

 

오른쪽의 Constraint Widget의 그림을 보면 안쪽의 선들이 꺾은선(>> <<)인 것을 알 수 있다.

그 부분에 커서를 갖다 대면 파랗게 변하면서 Wrap Content라고 나오는데 이는 뷰의 크기가 내용물을 채우도록 설정되어 있다는 의미이다. 밑의 Constraints 부분을 보면 확인할 수 있다.

 

이 꺾은선을 한 번 클릭하게 되면 선이 바뀌는데

 

 

직선이 되면서 버튼의 크기가 바뀌었다! 밑의 layout_width도 같이 바뀐 것을 볼 수 있다.

즉, 이 직선은 뷰의 크기가 지정한 값으로 설정되었다는 것을 의미한다.

 

여기서 한 번 더 누르면

 

 

구불구불한 선이 되면서 버튼이 match_constraint로 바뀐 것을 볼 수 있다.

 

결국 이 선들은 제약 조건을 쉽게 파악하고 설정할 수 있도록 도와주는 역할을 하는 것이다.

 

가이드라인(Guideline)


여러 개의 뷰를 일정한 기준에 맞춰 정렬할 때 사용한다.

뷰처럼 추가할 수 있지만, 크기가 0이고 화면에는 안 보이기 때문에 레이아웃에서는 없는 것으로 간주된다.

 

가이드라인 아이콘!

 

가이드라인에 연결

 

match_constraint


제약 레이아웃에서는 match_parent 대신 match_constraint를 지원한다.

처음에 이걸 사용할 때에는 match_parent와 똑같길래 그냥 이름만 다른 거구나~ 했는데 테이블 레이아웃을 공부하다가 그게 아니라는 걸 깨달았다.

 

말그대로 제약 조건에 맞추겠다는 뜻으로, 다른 뷰와의 위치 관계에 따라 크기가 정해진다. 속성 칸에서 0dp로 표시되는 것 또한 그런 이유이다.

 

그래서 뷰의 크기를 정하는 데 match_constraint를 선택했다면 제약 조건을 잘 설정해 주어야 한다. 

예를 들어 너비를 match_constraint로 설정하고 제약 조건을 한쪽만 연결하면 납작해지는데, 다른 한쪽을 연결해 주지 않아서 어디까지 뷰의 크기인지 모르기 때문이다.

 

 

간단한 예시.

제약 레이아웃은 화면 전체를 감싸고 있으며 버튼은 보다시피 세로만 match_constraint로 해 주었다.

왼쪽처럼 바닥을 부모에게 연결했을 때에는 화면을 꽉 채우게 되는데, 가이드라인에 연결하니 그 위치까지만 화면을 채우는 걸 볼 수 있다.

이처럼 위치를 이용해 크기를 설정하는 것이 match_constraint이다!

 

참고로 제약 레이아웃을 wrap_content로 하고, 안에 있는 뷰들을 모두 match_constraint로 하면 다들 납작해져서 난리가 나기 때문에 조심해야 한다. 사실상 크기 설정하는 것을 서로에게 미루는 셈이니 당연한 거겠지만...

 

메모

제약 레이아웃에서만 match_constraint를 지원하는 건, 다른 뷰들과의 관계가 레이아웃을 구성하는 데 가장 중요하게 작용하기 때문에 부모에 맞춘다라는 의미가 희미해져서인 것 같다!

 

개인적으로는 뷰에 하나라도 match_constraint를 쓰려고 할 때 레이아웃을 wrap_content로 설정하는 건 좀 위험한 것 같다.

match_constraint는 wrap_content나 dp에 비해 좀 더 제약 레이아웃스럽고(?) 크기도 일관성 있게 설정할 수 있다는 게 장점이지만, 그만큼 설정하는 데 바탕이 될 부모 레이아웃의 크기가 우선적으로 보장되어야 하기 때문이다.

여담


연결선을 자동으로 만들어 주는 기능도 있지만, 가끔 엉뚱하게 연결하는 경우도 많아서 직접 하는 게 좋은 것 같다.

 

 

 

https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout

 

ConstraintLayout  |  Android Developers

androidx.constraintlayout.core.motion.parse

developer.android.com

 

'안드로이드 > 안드로이드 앱 프로그래밍' 카테고리의 다른 글

7. 상대 레이아웃(RelativeLayout)  (0) 2023.04.13
6. 위젯  (0) 2023.04.13
5. 텍스트뷰(TextView)  (0) 2023.04.13
3. 리니어 레이아웃(LinearLayout)  (0) 2023.04.13
1. XML  (0) 2023.04.12