[Android] About ConstraintLayout

오늘은 최근에 사용하기 시작한 ConstraintLayout에 대해 이야기해볼까 합니다.
“이제야 ConstraintLayout을 사용하기 시작했다구요!?”
네.. 그렇습니다.
두달 전까지만 해도 저는 LinearLayout과 RelativeLayout을 이용해 UI를 그렸습니다.
하지만 새 프로젝트를 시작하며 ConstraintLayout과 CoordinatorLayout을 사용해보고는 자연스럽게 LinearLayout과 RelativeLayout의 사용 빈도가 줄어 들었습니다.
특히 RelativeLayout은 더욱요.

ConstraintLayout

이 단어를 검색하기만 해도 수많은 사이트들이 쏟아져나올겁니다.
한 2년 전 쯤에 처음 접한것 같아요.
한창 LinearLayout과 RelativeLayout을 사용하는 제게는 굳이 왜 써야되는지 이해가 안갔습니다.

장점

같은 코드 맞아?

어떤 화면이 있다고 가정합니다.

아래의 코드는 화면을 RelativeLayout과 LinearLayout으로 표현한 코드입니다.
코드가 너무 길어지기 때문에 큰 틀만 보도록 할게요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<RelativeLayout>
<ImageView/>
<ImageView/>
<RealativeLayout>
<TextView/>
<LinearLayout>
<TextView/>
<RelativeLayout>
<EditText/>
</RelativeLayout>
</LenarLayout>
<LinearLayout>
<TextView/>
<RelativeLayout>
<EditText/>
</Relativelayout>
</LinearLayout>
<TextView/>
</RelativeLayout>
<LinearLayout>
<Button/>
<Button/>
</LelativeLayout>
</RelativeLayout>

아래는 같은 화면을 ConstraintLayout으로 표현한 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
<ConstraintLayout>
<ImageView/>
<ImageView/>
<TextView/>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
<TextView/>
<Button/>
<Button/>
</ContraintLayout>

말이 필요 없네요.
화면에 보여줘야할 뷰가 많아지면 많아질수록 코드는 기하급수적으로 차이날 겁니다.

마치 그리듯

UI 화면에서 ConstraintLayout안에 뷰를 끌어다 이리저리 위치시키면 됩니다.
그리고 배치한 뷰의 상하좌우 가운데에 있는 ㅇ를 끌어다가 제약조건을 추가하면 됩니다.
제약 조건에 따라 뷰가 스르륵 움직이며 어떤 배치인지 다시 나타납니다.

“A는 B의 오른쪽에 위치하고 윗줄은 D와 나란히..”

아래와 같이 직관적으로 표현됩니다.

예쁜 뷰를 빠르게

다시 위에서 보여준 사진을 봅시다.
키패드와 키패드의 간격이 모두 16으로 설정되어있습니다.
RelativeLayout으로 이것을 구현하려면 해당 뷰의 margin을 찾아서 직접 입력해야 합니다.
하지만 ConstraintLayout에는 뷰와 뷰 사이의 기본 margin을 설정할 수 있습니다.
위에서 그리듯 제약조건을 추가하면 기본으로 8dp의 제약조건이 설정되어 있고 사용자 임의로 간격을 수정할 수 있습니다.

이미 배치한 뷰의 margin을 수정해야 할때는요?
소스코드 바다를 해맬 필요가 없습니다.
View Attribute 상단에 우선적으로 margin을 설정할 수 있도록 안드로이드 스튜디오가 지원하고 있습니다.

진입장벽

팀원 요청에 따라 ConstraintLayout을 사용하는 방법을 가이드했습니다.

  1. 이전처럼 뷰를 ConstraintLayout안에 배치하구요
  2. ㅇ 버튼을 눌러 제약조건이 필요한 부분에 끌어다 놓습니다.
  3. 뷰를 부모 뷰 가운데 위치하고 싶다면 상하좌우 제약조건을 부모 뷰 상하좌우에 설정하세요.
  4. 여기 기본적으로 margin이 설정되어 있으니 필요에 따라 수정하세요.

10분도 안돼서 가이드는 끝났습니다.
그리고 이런 피드백이 왔습니다.

이정도면 UI 그릴만 한데..? 내가 할까? ㅋㅋㅋ

추가로

이 포스트를 쓰면서 알게된 것인데 화면을 처리하는 속도에도 영향이 있다고 합니다.

사용자가 뷰를 보기까지 안드로이드는 3단계를 거칩니다.

  1. 측정
  2. 레이아웃
  3. 그리기

측정 단계에서는 View의 크기를 결정합니다.
측정 노드는 루트 노드에서 시작해서 반복적으로 호출되며, 각각의 호출은 부모로부터 전달된 인자들과 함께 발생합니다.

레이아웃 단계에서는 각각의 view 크기를 기준으로 view의 위치를 결정합니다.
루트 노드에서 시작해서 말단 노드까지 반복적으로 호출됩니다.

그리기 단계는 스크린에 자신을 그리는 단계입니다.
RelativeLayout이 자신을 화면에 그리라는 요청을 받게 되면 자식들에게 자신을 측정하라는 메세지가 전달되며
모든 view가 측정될 때까지 이 과정이 계속됩니다.
중첩된 레이아웃이 많을수록 측정하는데 걸리는 시간도 늘어나게됩니다.

단점

생각보다 느립니다.

위에서 설명한 제약조건이나 뷰를 다시 배치했을때 즉각 반응한다기 보단 조금 기다려야 합니다.

내가 원하는 소스코드랑 다른데…

ConstraintLayout뿐만 아니라 예전부터 고질병처럼 쫓아오는 단점입니다.
드래그 앤 드롭으로 UI를 그리면 내가 원하지 않는 소스코드들이 덕지덕지 붙어있습니다.
굉장히 신경쓰이는 부분입니다.

결론

위의 단점에도 불구하고 장점이 강력하기 때문에 앞으로도 계속 사용 될 것입니다.

마무리

제 경험에 비추어 ConstraintLayout에 대해서 적어봤습니다.
이 포스트에서 언급하지 않았지만 체인, 비율 등의 장점도 있습니다.