android ConstrainLayout

2020. 8. 24. 13:56android

1. 반응형 레이아웃이란?


반응형 레이아웃이란 보여지는 화면이 기기에 따라서 동일한 비율로 나타내지는 것을 의미합니다. 모바일 시장이 점점 더 고도화 되면서, 다양한 해상도를 갖는 기기가 출시되고 있습니다. 때문에 반응형 레이아웃을 잘 구성하는 것 또한 중요한 문제입니다. 

2. ConstrainLayout


컨스트레인 레이아웃은 LinearLayout 과 RelativeLayout의 장점을 모두 섞어 놓은 레이아웃입니다. 때문에 리니어레이아웃이 갖는 가중치(weight)의 장점과 랠러티브레이아웃이 갖는 체인(chain)을 연결하는 장점을 혼재시켰습니다. 처음 ConstrainLayout을 사용하면 다소 어렵게 느껴질 수 있지만 UI를 구성하기 위해서 레이아웃을 중첩시켜야 하는 일을 view들의 chain의 연결과 가중치를 사용하여 보다 쉽고 직관적으로 해결할 수 있습니다. 

3. 왜 써야할까?


컨스트레인레이아웃이 대강 뭔지는 알겠지만 왜 써야할까요? 크게는 두가지 정도의 이유를 들 수 있을 것 같습니다.

 

1) 뷰의 비율

리니어레이아웃의 장점인 가중치를 가져왔다고 했습니다. 때문에 굳이 리니어레이아웃을 선언할 필요없이 컨스트레인 레이아웃에서 뷰의 비율을 정할 수 있습니다.

 

2) view 상호 관계를 정의할 수 있다.

- 릴러티브레이아웃에서는 자식 view 간 상호관계를 정의할 수 없었지만 컨스트레인레이아웃에서는 뷰 간의 상호관계를 정의할 수 있기 때문에 직관적으로 관계 파악이 가능합니다.

 

즉 유지보수는 더욱 더 편해지고 레이아웃을 중첩하는 일을 적게 만들기 때문에 유지보수에 아주 유용합니다.

3. chain 사용법 


먼저 chain을 사용하기 위해서는 constrainLayout만의 문법을 조금 알고 있어야합니다. 

 

layout_constraintXXX_toXXXof

 

X표시를 한 곳에 start(left),end(right), top, bottom이 들어가면 됩니다. 

 

1) XXX

- 파란색으로 칠해진 X표시는 현재의 view가 기준입니다. 즉 현재 설정하고 있는 view입니다. 예를 들어 XXX부분에 start가 들어간다면 현재 view의 왼쪽을 의미하게 됩니다. 마찬가지로 XXX부분에 top이 들어간다면 현재 view의 top을 지칭하게 됩니다. 

 

2) XXX

- 빨간색으로 칠해진 X가 바로 기준을 삼고자하는 다른 view의 부분입니다. 따라서 현재 설정하고 있는 A라는 뷰가 B라는 뷰의 왼쪽과 상호 관계를 맺을 것인지, 아래쪽과 관계를 맺을 것인지에 대한 기준을 정하는 부분입니다. 예로 

 

layout_constrintToEnd_toStartOf

 

이라고 한다면 현재 작업 중인 view의 end(right)와 기준으로 삼고자 하는 다른뷰의 start(left)와 상호 관계를 맺겠다는 의미가 됩니다. 

 

(참고로 상하, 좌우 별로 chain이 걸린다면 view의 배치가 자동으로 할당됩니다. 따라서 왼쪽에 붙이있게 하고 싶으면 start부분만 선언하고 end부분을 선언하지 않게 되면 왼쪽에 붙어있게 됩니다. 이런 방법을 통해서 위쪽, 아래쪽 등을 설정하면 쉽습니다.) 

4. match_constraint


컨스트레인레이아웃에는 match_constraint가 있습니다. 쉽게 정의하자면 제약이 걸려 있는 공간을 최대로 할당되는 것을 의미합니다. 한마디로 위에서 배운 체인 제약을 모두 걸어놓은 상태에서 공간을 모두 match하는 것을 의미합니다.

 

주로 width, height에서 사용하게 됩니다. 하지만 wrap_parent, match_parent처럼 사용하는 것이 아니라 0dp로 사용하고 이를 match_constraint라고 읽습니다.

5. view 배치


1) EditText

- match_constraint를 이용하여 버튼의 왼쪽부분까지 textView의 width를 배치합니다. 이렇게 view의 비율을 설정할 수 있기 때문에 굳이 LinearLayout을 사용할 필요가 없어지므로 viewgroup의 중첩이 사라져 직관적으로 이해하기 더 쉽습니다.

 

2) Button

- 아래 코드를 보면 더 잘 이해할 수 있겠지만 오른쪽 상단에 배치하기 위해서 chain을 end와 top부분만 설정하여 배치하였습니다. 이렇게 parent를 기준으로 view와의 관계 뿐만아니라 viewGroup인(parent) 레이아웃과도 연관관계를 지음으로써 간편하게 view를 배치할 수 있습니다. 

 

3) TextView

- EditText와 Button 이외의 모든 공간을 차지하기 위해서 마찬가지로 match_constraint를 사용합니다. 이로인해 chain에 연결한 모든 공간을 할당받게 되므로 해상도 별로 달라져도 자동으로 핸들링하여 공간을 배정하게 됩니다. 

 

 

6. main.xml


7. chainStyle


왼쪽의 그림처럼 parent인 constrainLayout과 자식 버튼1~3번의 좌우를 모두 연결하면 기본적으로 해상도에 맞게 적절한 view가 자동으로 배치가 됩니다. 하지만 이렇게 자동으로 뷰가 배치되는 것 이외에 chainStyle을 변경할 수 있습니다. 

 

여기서 가장 중요한 점은 제약조건을 모든 viewGroup과 view에게 주는 것이 아닌 가장 왼쪽에 있는 button1에게만 조건을 할당함으로써 chainStyle을 변경해야 하는 것입니다. 이유는 컨스트레인 레이아웃에서 chain의 헤드가 가장 왼쪽 혹은 가장 상단에 있는 view를 기준으로 하기 때문입니다.

 

chainStyle은 3가지 정도의 style이 존재합니다.

 

1) spread: 왼쪽 이미지처럼 view 간격이 배치됩니다.(default)

 

2) spread_inside: 공간을 최대한 활용하는 방법으로 사이드에 있는 view들은 각 측면으로 배치가 되고 중앙의 중앙의 view는 가운데로 정렬됩니다. 

 

3) packed: chain으로 연결된 view들이 중앙으로 밀집됩니다. 

8. xml


9. 꿀팁(?)


그 동안 컨스트레인 레이아웃을 사용하면서 가장 편하게 view들과의 관계를 배치하는 나름의 방법을 알게 되었는데요. 도움이 되셨으면 좋겠습니다.

 

예로 배달의 민족 app을 들어보겠습니다. 배민 app을 들어가게 되면 동그란 아이콘 밑에 해당 버튼에 대한 name이 나타납니다. 그것도 버튼에 정 중앙에 이쁘게 배치가 됩니다. 그것도 한 두개가 아닌 여러 개를 이쁘게 배치하고 있습니다. 제가 만든 앱에도 이처럼 구현하기 위해서 이렇게도 해보고 저렇게도 해봤는데 쉽지 않더라구요!

 

몇 시간 동안 삽질하다가 친구들이랑 놀려고 만나서야 불현듯이 뇌리에 방법이 스치더라구요ㅎㅎ 방법은 바로 자신의 start와 end를 기준으로 삼을 view의 start와 end에 상관관계를 맺도록 하는 것입니다.

 

이렇게 Button의 start와 end부분을 textView의 start와 end부분과 상관관계를 맺으면 button들을 기준으로 textView의 위치가 이쁘게 배정되는 것을 볼 수 있습니다. 

 

 

10. 꿀팁의 xml