ANDROID 프로그래밍/LAYOUT

안드로이드 컨스트레인트레이아웃. (Android ConstraintLayout)

뽀따 2019. 4. 8. 11:30


1. 안드로이드 레이아웃 작성.

안드로이드 앱을 개발할 때, UI 화면을 구성하는 작업은 보기만큼(?) 마냥 쉬운 일이 아닙니다. 특히 앱 개발 경험이 상대적으로 부족한 초보 개발자들에겐, 앱의 탐색 메뉴 구성과 컨테이너 선택, 그리고 각 화면에 들어갈 레이아웃과 뷰 위젯 등을 결정하는 일이, 비즈니스 로직(business logic)을 구현하는 작업보다 우선적으로 해결해야 할 과제로 여겨지기도 하죠. 게다가, 요구사항의 변경으로 인해 화면 요소의 배치를 빈번하게 수정해야 하는 일이 발생하면 UI 화면을 수정하는데에만 전체 개발 시간의 상당 부분을 소비하게 될지도 모릅니다.


그러므로 안드로이드 UI 컴포넌트의 종류와 특성, 사용법을 정확히 이해하고 사용하는 것은 매우 중요한 일입니다. 특히, 뷰 위젯을 화면에 배치하기 위해 사용하는 레이아웃(Layout)은, 화면 구성이 복잡할수록, 또, 사용되는 뷰 위젯의 갯수가 많을수록, 어떤 종류의 레이아웃(들)을 선택하는지가 화면 구성 시간, 동작 성능, 유지보수 등에 영향을 줄 수 있습니다.


과거, "UI 구성의 유연함"보다 "배치의 직관성"이 중요시되던 시기에는, 여러 종류의 레이아웃을 중첩(nested)하여 UI를 구성하는 경우가 많았습니다. 사용하기 쉽고, 설계에 따른 화면 구성이 용이했기 때문인데요. 하지만 레이아웃을 중첩해서 사용하는 방법은 성능과 유지보수 측면에서 그다지 효율적이지 못한 단점이 있습니다.


그래서, 레이아웃을 중첩(nested)하지 않고 유연한 방법으로 뷰 위젯들을 배치할 수 있는 레이아웃이 만들어지게 되었습니다. 렐러티브레이아웃(RelativeLayout)의 "상대적 위치 관계에 따른 배치" 특성에 리니어레이아웃(LinearLayout)의 "가중치(weight)가 가진 장점"을 적용하고, 체인(chain) 사용으로 다른 레이아웃 없이 "요소들을 그룹화"할 수 있는, 그리고 그 동안 유명무실(?)했던 레이아웃 에디터를 적극 활용하여 좀 더 쉽고 빠르게 화면을 구성할 수 있게 만들어주는 레이아웃. 바로 컨스트레인트레이아웃(ConstraintLayout)입니다.

2. 안드로이드 컨스트레인트레이아웃(ConstraintLayout) 클래스

컨스트레인트레이아웃(ConstraintLayout)은 레이아웃 구성 시, 뷰 위젯의 위치와 크기를 유연하게 조절할 수 있게 만들어주는 레이아웃입니다. 음.. 너무 추상적인 표현이죠? 조금 더 구체적인 내용부터 차근차근 알아보겠습니다.


컨스트레인트레이아웃이 어떠한 방식으로 레이아웃 배치의 유연함을 제공하는지는, "컨스트레인트(Constraint)"라는 단어의 의미를 통해 유추할 수 있습니다. 바로 Constraint, "제약(또는 조건)"이죠.


컨스트레인트레이아웃는 레이아웃에 배치되는 뷰들에 여러 제약(Constraint)을 적용하여 각 뷰의 위치와 크기를 결정합니다. 여기서 말하는 "제약(Constraint)"이란, 각 요소들의 최종 위치와 크기를 결정하게 될 조건, 예를 들어, 특정 뷰 왼쪽 사이드를 지정된 뷰의 오른쪽 사이드에 맞추거나, 뷰의 왼쪽,오른쪽 사이드를 각각 부모 레이아웃의 왼쪽,오른쪽 사이드에 맞추는 것 등을 말하며, 이러한 각각의 제약(Constraint)은 컨스트레인트레이아웃이 가지는 하나의 레이아웃 속성으로 매핑됩니다. (이런 이유로, 본문과 이후 컨스트레인트레이아웃 관련 글에서는 제약(Constraint)과 속성이라는 용어를 섞어서 사용한다는 점 참고하시기 바랍니다.)

3. 컨스트레인트레이아웃 속성 기본 사용법.

컨스트레인트레이아웃이 제공하는 "제약(Constraint)"들, 즉, 컨스트레인트레이아웃 속성의 이름은 기본적으로 "layout_constraint"로 시작하며, 바로 뒤에 구체적인 제약 조건이 명시됩니다.


예를 들어, 뷰의 "왼쪽 사이드를 대상 뷰의 오른쪽 사이드에 배치"하는 속성은 "layout_constraintLeft_toRightOf"입니다. "layout_constraint"에 "Left_toRightOf"라는 제약 조건을 결합하여, 뷰의 왼쪽 사이드(Left)를 속성 값으로 지정된 ID 뷰의(Of) 오른쪽 사이드(ToRight)에 맞추라는 제약을 지정할 수 있습니다.


앱 개발 시, 레이아웃을 구성할 때는, 아래와 같이 XML 코드를 작성합니다.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="48sp"
        android:background="#FF0000"
        android:id="@+id/text1"
        android:text="TEXT1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="48sp"
        android:background="#00FF00"
        android:id="@+id/text2"
        android:text="TEXT2"
        app:layout_constraintLeft_toRightOf="@id/text1" />

</android.support.constraint.ConstraintLayout>


4. 컨스트레인트레이아웃이 제공하는 제약(Constraint).

컨스트레인트레이아웃이 제공하는 제약(Constraint)은 그 종류가 매우 많으며, 사용 목적과 방법에 따라 몇 가지 카테고리로 분류됩니다, 물론, 컨스트레인트레이아웃을 사용하는데 있어, 하나의 속성 또는 하나의 카테고리에 속한 속성들만 사용할 수 있는 것은 아니며, 필요에 따라, 여러 카테고리의 제약들을 다양하게 조합하여 사용합니다.


아래 그림은 컨스트레인트레이아웃에서 사용할 수 있는 제약(Constraint)들을 카테고리로 구분하여 정리한 내용인데요, 카테고리에 대한 분류와 기본적인 설명은 [안드로이드 개발 참조문서. ConstraintLayout]에서 참고할 수 있습니다.



아래 표의 항목을 클릭하면, 각 항목에 대한 좀 더 상세한 설명과 예제를 확인할 수 있습니다.


카테고리 설명
Relative positioning 요소 간 상대 위치 지정. (left, right, top, bottom, start, end, baseline)
Margins 요소 간 여백(Margin) 설정을 위한 제약.
Centering positioning 뷰를 부모 레이아웃 또는 제약 영역의 중앙에 배치.
Circular positioning 대상 뷰를 기준으로 각도(angle)와 반지름(radius)으로 상대 위치 지정.
Visibility behavior 뷰의 Visibility 상태에 따른 최종 위치 결정 및 여백.
Dimension constraints 뷰에 적용된 제약에 따른 뷰의 크기(Dimension) 결정.
Chains 수평 또는 수직 방향(Axis)으로 나열된 뷰에 대한 그룹화. 배치 스타일 지정.
Virtual Helpers objects 레이아웃 내 효율적인 뷰 배치에 사용 가능한 몇 가지 Helper 객체들.
(Guideline, Barrier, Group)
Optimizer 제약 카테고리에 대한 최적화.


아래 표는 컨스트레인트레이아웃에서 제공하는 속성을 나열한 것입니다. 각 속성 이름을 클릭하면, 해당 속성에 대한 자세한 설명을 확인할 수 있습니다.


ConstraintLayout 속성 설명
layout_constraintLeft_toLeftOf 뷰의 왼쪽 사이드(Side)를 대상 뷰의 왼쪽 사이드(Side)에 맞춤.
layout_constraintLeft_toRightOf 뷰의 왼쪽 사이드(Side)를 대상 뷰의 오른쪽 사이드(Side)에 맞춤.
layout_constraintRight_toLeftOf 뷰의 오른쪽 사이드(Side)를 대상 뷰의 왼쪽 사이드(Side)에 맞춤.
layout_constraintRight_toRightOf 뷰의 오른쪽 사이드(Side)를 대상 뷰의 오른쪽 사이드(Side)에 맞춤.
layout_constraintTop_toTopOf 뷰의 위쪽 사이드(Side)를 대상 뷰의 위쪽 사이드(Side)에 맞춤.
layout_constraintTop_toBottomOf 뷰의 위쪽 사이드(Side)를 대상 뷰의 아래쪽 사이드(Side)에 맞춤.
layout_constraintBottom_toTopOf 뷰의 아래쪽 사이드(Side)를 대상 뷰의 위쪽 사이드(Side)에 맞춤.
layout_constraintBottom_toBottomOf 뷰의 아래쪽 사이드(Side)를 대상 뷰의 아래쪽 사이드(Side)에 맞춤.
layout_constraintBaseline_toBaselineOf 뷰의 텍스트 Baseline을 대상 뷰의 텍스트 Baseline에 맞춤.
layout_constraintStart_toEndOf 뷰의 시작 사이드(Side)를 대상 뷰의 끝 사이드(Side)에 맞춤.
layout_constraintStart_toStartOf 뷰의 시작 사이드(Side)를 대상 뷰의 시작 사이드(Side)에 맞춤.
layout_constraintEnd_toStartOf 뷰의 끝 사이드(Side)를 대상 뷰의 시작 사이드(Side)에 맞춤.
layout_constraintEnd_toEndOf 뷰의 끝 사이드(Side)를 대상 뷰의 끝 사이드(Side)에 맞춤.
layout_goneMarginLeft 뷰 위젯의 왼쪽(Left) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_goneMarginTop 뷰 위젯의 위(Top) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_goneMarginRight 뷰 위젯의 오른쪽(Right) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_goneMarginBottom 뷰 위젯의 아래(Bottom) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_goneMarginStart 뷰 위젯의 시작(Start) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_goneMarginEnd 뷰 위젯의 끝(Start) 사이드 대상 뷰가 View.GONE 상태일 때 여백 설정.
layout_constraintHorizontal_bias 수평 방향(Left/Right 또는 Start/End) 사이드 제약 시, 양 사이드 간 위치 비율.
layout_constraintVertical_bias 수직 방향(Top/Bottom) 사이드 제약 시, 양 사이드 간 위치 비율.
layout_constraintCircle 원형 위치 지정에 사용될 대상 뷰 ID 지정.
layout_constraintCircleRadius 원형 위치 지정 시, 뷰 위젯과 대상 뷰 위젯 중심 사이의 거리.
layout_constraintCircleAngle 원형 위치 지정 시, 원 둘레에서 뷰 위젯이 배치될 각도.


5. 참고.

.END.