안드로이드에서 xml 파일의 구조를 설계하기 위해 사용하는 레이아웃에는 여러가지가 있습니다. View 간의 상대적인 위치를 잡아주는 ConstraintLayout과 RelativeLayout, 리스트와 같은 직관적인 구조를 만들 수 있는 LinearLayout, 액자식 구조를 만들 수 있는 FrameLayout 등 앱의 용도와 디자인에 따라 알맞게 사용할 수 있습니다. 그 중에서 가장 유용하게 사용되는 ConstraintLayout과 LinearLayout에 대해서 알아보겠습니다. 사실 상 이 두가지만 알아도 어지간한 형태의 앱은 만들 수 있습니다. (물론 가끔씩 FrameLayout 같은 것들이 필요하기도 하지만요.)
1. ConstraintLayout
ConstraintLayout은 RelativeLayout을 어느 정도 보완할 만한 레이아웃입니다. 뷰의 상대적인 위치를 잡아준아는 점에서는 RelativeLayout과 유사하지만 훨씬 유연하고 직관적으로 사용할 수 있죠. xml 파일을 만들 때 가장 처음에 존재하는 것이 이 ConstraintLayout입니다.
그런데 ConstraintLayout 위에 뷰를 올려놓고 빌드해보면 뭔가 의도한 대로 되지 않는데요, 이것은 ConstraintLayout의 특성을 제대로 파악하지 않고 사용했기 때문입니다. 어떻게 해야 의도한대로 앱을 표현할지 한번 알아봅시다. 일단은 대충 아무렇게나 올려놓고 빌드해 봅시다. 빌드를 하게 되면 아래의 사진과 같이 안드로이드 스튜디오 내에서 의도한대로 뷰가 표현되지 않습니다. 이유가 뭘까요?
'Constraint'는 제약 조건이라는 뜻이 있습니다. 즉 여기서 말하는 제약 조건이란 어떤 뷰의 최종적인 위치를 정하게 될 조건을 말하게 됩니다. 예를 들어 위의 사진에서는 버튼 2개와 자그마한 이미지 1개, 텍스트뷰 1개를 올려 놓았는데, 우리는 각 뷰를 적당히 '여기에 놓으면 이쁠 것 같다'라는 식으로 위치를 정했을 뿐이지 버튼은 화면의 왼쪽 모서리를 기준으로 얼마 만큼 떨어진 곳에 위치하며, 윗쪽 모서리를 기준으로 얼마 만큼 떨어진 곳에 위치해야 하는 지를 정하지 않았습니다.
조금 더 쉽게 말하자면 좌표를 잡아주지 않았다고 보면 좀 쉬울 것 같네요. 그림으로만 본다면 뭔가 좌표가 잡혀져있는 것 처럼 보일 수 있지만, "화면에서 이쯤" 이라는 추상적인 위치만을 가지고 있으며, 우리는 컴퓨터에게 뷰의 좌표를 넘겨준 적이 없기 때문에 컴퓨터가 이 뷰가 어디에 위치해야할 지 알지 못해 자기도 되는대로 뷰를 배치하는 것입니다.
한마디로 뷰를 무엇을 기준으로 얼마 만큼 기준으로부터 떨어뜨려 놓을지 정하면 의도한대로 배치가 된다는 것입니다. 그렇다면 제약 조건, 즉 constraint을 거는 법을 배워봅시다.
1-1. constraint 정하기
constraint를 지정하는 방법은 여러 가지 방법이 있습니다.
1) 아래의 그림과 같이 뷰를 클릭했을 때 주변에 생기는 동그라미를 눌러 드래그하여 화살표 방향으로 끌어다 놓으면 됩니다. 뷰 사이의 constraint를 정할 때도 마찬가지입니다. 다만 상, 하, 좌, 우에 정확하게 끌어다 놓아주세요.
2) 간단하게 부모 레이아웃에 constraint를 지정할 것이라면 Component Tree에 있는 뷰를 우클릭하고, Constraint -> parent top을 눌러주면 위쪽 모서리를 기준으로 뷰가 배치될 것입니다. 다른 위치들도 마찬가지입니다.
3) 빨간 박스 안의 파란색 + 버튼을 눌러보세요. contraint를 정함과 동시에 얼마 만큼 떨어뜨려 놓을지도 정할 수 있습니다.
1-2. constraint 구조 이해하기
이해를 조금 더 쉽게 돕고자 위와 같은 구조를 만들어 봤습니다. 가장 아래에 있는 버튼부터 위로 올라가는 순서대로 root1, child1, child2, child3이라고 이름 지어봤습니다. 각 버튼은 Horizontal 좌표는 왼쪽을 기준으로 적당히 떨어뜨려 놓았습니다. 사진과 같이 왼쪽 constraint 만 잡아두면 오른쪽은 굳이 잡을 필요가 없습니다. 어차피 남은 길이 만큼이 오른쪽 constraint가 되는 것이니까요. 그 반대도 마찬가지입니다.
root1은 아랫쪽 모서리를 기준으로 위치가 잡혀 있으며, child1은 화살표처럼 root1에 따라 위치가 잡히게 되며, child2, child3는 각각 child1, child2의 위치에 따라 vertical 좌표가 결정됩니다. 즉 위와 같은 구조를 만들고 root1을 움직여보면 알겠지만, child1, child2, child3는 root1이 상하로 움직이는 만큼 똑같이 움직이게 됩니다. 즉 기준점이 되는 view의 위치를 잘 잡지 않으면 아래의 사진과 같은 문제가 발생할 수 있습니다.
제일 위쪽의 child3가 아슬아슬하게 붙어 있습니다. root1을 조금만 더 위쪽으로 올렸다면 짤렸을 수도 있겠군요. 따라서 뷰를 여러 개를 나열했을 때 위와 같이 짤리는 현상이 발생하지 않게 하기 위해선 상, 하, 좌, 우에서 가장 모서리에 가까운 뷰를 기준 뷰로 잡고 나머지 뷰들을 기준 뷰의 child로 들어가게 설계하면 좋습니다.
위와 같이 root1과 root2를 사이에 두고 뷰를 배치하게끔 만들어주면 좋습니다.
ConstraintLayout의 기능은 상당히 방대하기 때문에 공식 문서를 보면서 익히는 것이 가장 좋습니다. 다만 제약 조건을 설정하는 법만 어느 정도 알아도 사용하는 데에 큰 무리는 없을 것이라고 생각합니다.
https://developer.android.com/training/constraint-layout?hl=ko
2. LinearLayout
ConstraintLayout보다 훨씬 직관적인 구조를 설계할 수 있기 때문에 설명하는 데에 크게 오래 걸리진 않을 것 같습니다. 마치 표를 그리고 선을 그어서 칸을 만들고 칸 안에 뷰를 넣는 것과 같다고 생각하면 됩니다.
위의 사진은 vertical LinearLayout을 만들고 그 안에 버튼을 여러 개 넣은 것입니다. 버튼이 수직으로 정렬되는 것을 확인할 수 있습니다. 수평으로 정렬하고 싶다면 LinearLayout (horizontal)을 사용하시면 됩니다.
그렇다면 테이블에서 셀을 나누듯이, 또는 표와 같은 형태로 만들고자 한다면 어떻게 하면 될까요? 물론 테이블을 만들기 위해 LinearLayout을 사용하는 것은 아니지만, 조금만 응용한다면 여러 개의 LinearLayout 만으로 테이블 형태를 만들 수 있습니다. 아래의 사진과 같이 말이죠.
댓글
댓글 쓰기