본문 바로가기

Android/UI

[XML] ConstraintLayout.. LinearLayout.. 각종 Layout을 알아보자!

Layout

- Layout??

Layout은 ViewGroup의 일종으로 다른 뷰들을 내부에 배치하는 역할을 수행한다. Layout은 내부에 위젯이나 다른 Layout을 내부에 배치함으로써 다양한 화면을 구성한다. 일반적으로 Layout은 화면 상에 직접 보이지 않는다. Layout 파일은 애플리케이션의 Layout 구조를 설명하며, View 및 ViewGroup 요소를 구성하고 배치하는데 사용된다. Layout 파일은 리소스 디렉터리(res/layout)에 저장되며, 애플리케이션 코드에서 인플레이트(inflate)하여 실제 UI를 생성한다.

 

UI를 구성할 수 있는 Layout에는 여러가지 종류가 있는데 한번 차근차근 알아보자

 

- ConstraintLayout

ConstraintLayout은 필자가 가장 좋아하고 추천하는 Layout이다. ConstraintLayout이란 상대 위치에 따라 유연하게 Widget의 위치와 크기를 지정할 수 있는 Layout이다 즉, View간의 상대적 제약조건(Constraint)을 만들 수 있는 Layout을 뜻한다. 상대적 제약조건이란 특정 뷰가 다른 View에 대해 위(Top), 아래(Bottom), 왼쪽(Start), 오른쪽(End)에 위치할 수 있는지를 정의한 조건을 뜻한다.

 

아래에서 설명할 예정인 Linear, Relative 등 여러 Layout들에 비해 서로 ViewGroup이 중첩하지 않게 하면서 복잡한 UI를 그려낼 수 있다는 장점이 있다.

 

위에서 설명한 제약조건의 유형은 크게 9가지가 있다.

- Relative positioning (상대적 위치지정) : 다른 요소와 수평, 수직방향의 상대적 배치를 위한 속성

- Margins (여백) : 여백 설정을 위한 속성

- Centering positioning (중앙 위치지정) : 중앙 배치를 위한 속성

- Circular positioning (원형 위치지정) : 다른 요소와 원 형태의 상대적 배치를 위한 속성

- Visibility behavior (가시성 동작) : visibility 속성에 따른 동작 속성

- Dimension constraints (크기 제약) : 뷰의 크기를 위한 속성

- Chains (연결) : 수평 또는 수직방향으로 연결된 뷰를 위한 속성

- Virtual Helpers objects (가상의 도움 객체들) : 뷰의 배치에 도움을 줄 수 있는 객체 속성

- Optimizer (최적화) : 제약조건 최적화 속성

 

 

- 사용방법

ConstraintLayout은 View를 화면에 그려줄때 앞서 설명한 것 처럼 제약조건을 지정해줘야 한다. ConstraintLayout에서 그려지는 View들은 필수적으로 가로, 세로에 하나씩 제약조건이 있어야 한다.

 

즉, Start, End 중 하나, Top, Bottom중 하나씩의 제약조건이 필요하다.

 

아래의 예시를 보고 한번 이해해보자!

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

위와 같은 속성으로 Button을 만든다면 사진과 같은 모습으로 View가 그려질 것이다.

 

여기서 parent가 뭔지 궁금한 독자들이 있을텐데 parent는 쉽게 말하자면 각 화면의 양끝을 얘기한다. 쉽게 말해 그리고자 하는 View의 Top(View의 윗 부분)의 속성으로 Top(View가 그려지는 화면의 윗부분)의 parent를 준다면 위의 예시 그림과 같이 View의 Top(View의 윗 부분)이 화면의 최상단으로 연결된 것을 볼 수 있다. 이는 Bottom, End, Start 모두 똑같다.

 

자 그럼 여기서 그러면 parent로만 View의 위치 조정 속성을 줄 수 있는거 아니야? 와 같은 생각이 들텐데 이 생각에 대한 답변은 아래의 예시로 확인하자!

<Button
        android:id="@+id/first_button" // View의 고유한 id값을 설정
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/second_button" // View의 고유한 id값을 설정
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/first_button"
        app:layout_constraintTop_toTopOf="parent" />

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

첫번째 예시와 다르게 id라는 속성이 추가되었는데 이를 이용해 사진속의 두번째 버튼의 Start(View의 앞부분)을 첫번째 생성했던 버튼의  id값을 이용해 End(View의 뒷부분)로 parent가 아닌 기존의 버튼의 id로 설정하여 서로 나열되게 배치할 수 있다는 것을 알 수 있다.

 

 

 

- LinearLayout

LinearLayout은 앞서 설명한 ConstraintLayout처럼 Android의 대표적인 Layout중 하나이다. LinearLayout은 개발자가 지정해 둔 방향대로 View를 쌓는 방식의 Layout이다. View들은 겹치지 않고 개발자가 먼저 선언한 View의 순서대로 Layout내에 하나씩 차곡차곡 배치된다.

 

LinearLayout은 쌓는 방식의 Layout답게 View의 배치 기준을 수평또는 수직으로 결정할 수 있다. orientation이라는 속성을 이용해 배치방향을 결정할 수 있다.

 

LinearLayout에서 중요한 속성을 알아보자.

- orientation="vertical" : 하위 View들을 수직방향으로 배치하는 속성

- orientation="horizontal" :  하위 View들을 수평방향으로 배치하는 속성

- layout_weight : 하위 View들의 가중치를 설정 (하위 View들의 크기 조정)하는 속성

- layout_gravity :ViewGroup의 gravity 속성에 의해서 결정된 원래 자기 자신의 위치에서의 중력 방향을 결정하는 속성

 

 

- 사용방법

LinearLayout은 View를 배치할때 앞서 설명한 orientation을 지정해줘야 한다. 방향을 설정해주어 배치하면 된다.

 

아래는 각각 horizontal, vertical을 적용한 코드와 화면이다.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"> // horizontal or vertical 

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종2" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종3" />

</LinearLayout>

horizontal 적용

 

vertical 적용

위와 같이 orientation 속성을 이용해 배치한 모습이다.

 

 

 

- RelativeLayout

RelativeLayout은 상대 View의 위치를 기준으로 정렬하는 Layout이다. 즉, View를 배치시에 다른 View와의 상대적 위치 관계를 설정하여 화면에 View를 배치하는 Layout이다.

 

기준이 되는 View로 위치 관계 설정시에 주의해야할 점이 있는데 앞서 ConstraintLayout에서 설명한 id라는 속성을 View별로 지정해주고 사용해야한다는 점이다.

 

RelativeLayout에서 중요한 속성을 알아보자.

- 배치

- layout_above : 기준 뷰의 위쪽에 배치하는 속성
- layout_below : 기준 뷰의 아래쪽에 배치하는 속성
- layout_toLeftOf : 기준 뷰의 왼쪽에 배치하는 속성
- layout_toRightOf : 기준 뷰의 오른쪽에 배치하는 속성

 

Align (정렬)

- layout_alignParentTop : 부모의 위쪽에 맞추는 속성
- layout_alignParentBottem : 부모의 아래쪽에 맞추는 속성
- layout_alignParentLeft : 부모의 왼쪽에 맞추는 속성
- layout_alignParentRight : 부모의 오른쪽에 맞추는 속성
- layout_centerHorizontal : 부모의 가로 방향 중앙에 맞추는 속성
- layout_centerVertical : 부모의 세로 방향 중앙에 맞추는 속성
- layout_centerInParent : 부모의 가로, 세로 중앙에 맞추는 속성

- layout_alignTop : 기준 뷰와 위쪽을 맞추는 속성

- layout_alignBottom : 기준 뷰와 아래쪽을 맞추는 속성

- layout_alignLeft : 기준 뷰와 왼쪽을 맞추는 속성

- layout_alignRight : 기준 뷰와 오른쪽을 맞추는 속성

- layout_alignBaseline : 기준 뷰와 텍스트 기준선을 맞추는 속성

 

 

- 사용방법

앞서 설명한 속성들을 이용하여 간단하게 View들을 배치해보겠다.

 

아래는 간단한 코드와 화면이다.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/first_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종1" />

    <Button
        android:id="@+id/second_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종2"
        android:layout_below="@id/first_button" // first_button 의 아래에 배치
        android:layout_toRightOf="@id/first_button"/> // first_button 의 오른쪽에 배치

    <Button
        android:id="@+id/third_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="종종3"
        android:layout_toRightOf="@id/second_button"/>// second_button 의 오른쪽에 배치

</RelativeLayout>

 

 

 

 

 

 

 

 

 

- TableLayout

TableLayout은 화면상에 마치 엑셀의 표 형식을 보는듯 나타내주는 레이아웃이다. 표 인만큼 각각의 Rows와 Columns를 가지고 표현할 수 있고, Background, Stroke, Color, Span등의 속성을 통해 원하는 모양으로 그릴 수 있다.

 

TableLayout의 주요 속성을 알아보자

- TableRows : 하나의 가로줄을 만드는 속성이다.

- layout_column : View가 추가될 열(Column)의 Index값 지정하는 속성

- layout_span : 2개 이상의 셀을 합치는 속성

- collapseCoulmns : 원하는 셀을 감추는 속성

 

 

- 사용방법

앞서 설명한 속성들을 이용해 간단하게 View를 배치해보겠다.

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종1" />

    </TableRow>

    <TableRow>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:text="종종2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:text="종종2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="종종2" />

    </TableRow>
</TableLayout>

 

 

- DrawerLayout

DrawerLayout은 본인의 하위 Layout 중 하나를 접거나 펼치고 접는 기능을 하는 Layout이다.  자식 레이아웃 중 하나에 layout_gravity 속성을 start(left)나 end(right)를 부여하는 것으로 DrawerLayout을 쓸 수 있다.  단, layout_gravity 속성을 가진 자식 레이아웃은 하나여야 하고 layout_height은 match_parent가 되어야 한다.

 

 

- 사용방법

간단하게 Layout을 배치해보겠다.

<androidx.drawerlayout.widget.DrawerLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="#FF4444"
            android:layout_gravity="start"
            android:gravity="center"
            android:padding="10dp"
            android:text="DrawerLayout 예제"
            android:textColor="#FFFFFF"
            android:textSize="30sp" />

    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF0000"
        android:gravity="center"
        android:padding="10dp"
        android:text="메인 화면"
        android:textColor="#FFFFFF"
        android:textSize="30sp" />


    <Button
        android:id="@+id/btn_open_drawer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF0000"
        android:padding="10dp"
        android:text="네비게이션 열기"
        android:textColor="#FFFFFF"
        android:textSize="20sp" />

</androidx.drawerlayout.widget.DrawerLayout>

위의 코드와 사진을 보면 DrawerLayout의 하위 LinearLayout을 생성하고 하위 Layout인 LinearLayout은 숨겨져있는 것을 볼 수 있다. 하위 Layout을 보이게 하는 버튼을 구현해주면 잘 동작할 것 이다.

 

 

 

앞서 설명한 Layout말고도 Android내에는 다양한 Layout이 존재한다.

글에서는 필자가 직접 사용해봤던 Layout들을 위주로 설명을 적어 다른 Layout들에 관한 내용이 빠져있을 수 있다.

이는 필자가 직접 사용해보고 따로 글을 작성해보도록 하겠다.

'Android > UI' 카테고리의 다른 글

[UI] DataBinding..? ViewBinding...?  (0) 2024.06.06
[UI] Compose SideEffect?  (0) 2024.05.24