안드로이드 레이아웃 공통사항. (Android Layout Common)

2016. 10. 7. 15:45


1. "layout_"으로 시작하는 속성.

Layout에 여러 View 위젯들을 사용하는 예제들을 살펴보면, 많은 속성들 중에 "layout_"으로 시작하는 속성들이 있는 것을 볼 수 있습니다. View가 부모 Layout에서 차지하는 영역의 크기를 지정하는데 사용되는 "layout_width"와 "layout_height", View와 부모 Layout 사이의 여백을 설정하기 위한 "layout_margin", 그리고 부모 Layout 내에서 View가 정렬되는 위치를 결정하기 위한 "layout_gravity" 등이 바로 "layout_"으로 시작하는 속성들이죠.


그런데 "layout_"으로 시작하는 속성들의 특징을 살펴보면 한 가지 공통점이 있는 것을 발견할 수 있습니다. 바로, "layout_" 속성이, View(또는 ViewGroup)가 자신의 배치 관련 설정을 부모 Layout에게 요청하는 역할을 한다는 것입니다. 즉, View에 사용되는 대부분의 속성들이 View 자체의 형태를 위한 속성이라면, "layout_"으로 시작하는 속성은 부모 Layout 내부에서 View가 가지는 크기, 여백, 위치 등을 설정하기 위한 속성인 것입니다.

layout_ 속성이 가지는 의미


하지만 "layout_"으로 시작하는 속성들을 사용한다고 해서, 그 속성 값이 View의 배치에 그대로 적용되는 것은 아닙니다. Layout 내에 있는 다른 View 위젯들의 속성 값 및 관계가 먼저 고려된 다음, 가능하다면 View 위젯의 속성 값이 최대한 반영되는 것이죠.


그럼 지금부터 "layout_"으로 시작되는 속성들에 대해 살펴보겠습니다.

2. Layout 또는 자식(Children) View 위젯에 적용될 수 있는 공통 속성

[안드로이드 레이아웃]에서 살펴봤듯이, Layout 클래스는 표시 형태 및 사용 용도에 따라 여러 종류가 존재합니다. 그리고 각 Layout의 용도에 맞게 다양한 속성이 제공되고 있죠. 하지만 화면에 차지하는 영역 크기, 여백, 정렬 등은 모든 Layout 및 자식(Children) View 위젯에 공통적으로 적용될 수 있는 속성입니다.

2.1 Layout 또는 View 위젯의 크기. (layout_width, layout_height)

Layout 또는 자식(Children) View 위젯을 사용할 때는 너비와 높이를 지정해야 합니다. 너비는 "layout_width" 속성을 사용하고, 높이는 "layout_height" 속성을 사용하여 지정합니다. layout_width 및 layout_height 속성에 크기를 지정할 때 100dp, 200px 등의 고정된 치수 값을 사용할 수 있지만, 일반적으로 고정 값 사용은 권장되지 않습니다. (만약 고정 값 사용이 필요하다면 dp 단위를 사용하시길 권장합니다.)


대신, "match_parent" 또는 "wrap_content" 중 하나의 값을 사용하는 것이 적당한 경우가 많습니다. match_parent는 Layout 또는 View 위젯을 상위 Layout이 허용하는 최대 크기에 맞게 늘릴 때 사용되는 값이며, wrap_content는 Layout 또는 View 위젯이 가진 내용에 맞는 크기를 갖게 하고자 할 때 사용되는 값입니다.


만약 Layout(검은 실선 영역)과 자식 View 위젯이 둘 다 wrap_content라면 아래와 같이 표시될 것입니다.

Layout wrap_content and View wrap_content


Layout과 자식 View 위젯이 모두 match_parent라면 아래와 같이 표시됩니다.

Layout match_parent and View match_parent


다음은 Layout이 match_parent이고, 자식 View 위젯이 wrap_content인 경우입니다.

Layout match_parent and View wrap_content


마지막으로 Layout이 wrap_content이고 자식 View 위젯이 match_parent인 경우, 둘 다 wrap_content인 경우와 동일한 출력 결과가 표시됩니다. 하지만 표시 결과가 어떤 식으로든 나온다고 하더라도, 상호 참조가 이루어지거나 기준이 모호한 정의는 피하는 것이 좋습니다.

Layout wrap_content and View match_parent


2.2 Layout 또는 자식(Children) View 위젯 요소 간 여백. (layout_margin, padding)

Layout에 자식 View 위젯들이 표시될 때, Layout과 View 위젯 사이 또는 인접한 두개의 View 위젯 사이에 여백을 위한 공간이 존재하지 않으면, 앱이 보여주고자 하는 내용의 가독성과 사용 편의성이 현저히 떨어지게 됩니다. 반대로 여백이 너무 많아도 유사한 문제가 발생하죠.

Layout Margin


이처럼 Layout과 View 위젯을 화면에 배치할 때는 각 요소 사이에 적절한 여백이 주어져야 하며, 안드로이드에서 여백으로 사용되는 속성에는 Margin과 Padding이 있습니다.


Margin은 View 위젯과 상위 Layout 사이에 주어지는 공간을 의미하며, View 위젯의 영역에 포함되지 않습니다. 반면 Padding은 View 위젯의 실제 내용(텍스트, 이미지 등)과 View 위젯 경계 사이의 추가적인 공간을 말합니다. View 위젯 영역에 포함되는 공간이죠.

Layout Margin and Padding


View 위젯에 Margin과 Padding을 적용하기 위해서는 각각 "layout_margin"과 "padding" 속성을 사용합니다.


아래는 layout_margin과 padding 속성에 "30dp"를 사용한 예제입니다.

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#FFFFFF">

        <ImageView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_margin="30dp"
            android:padding="30dp"
            android:background="#AAAAAA"
            android:src="@drawable/android_logo" />

    </LinearLayout>

Layout Margin and Padding Example 1


그리고 Margin과 Padding을 설정할 때, 상,하,좌,우 방향에 대해 개별적인 값을 사용할 수 있습니다. Margin을 각 방향에 대해 설정할 때는 "layout_marginTop", "layout_marginBottom", "layout_marginLeft", "layout_marginRight" 속성을 사용하고, Padding의 경우에는 "paddingTop", "paddingBottom", "paddingLeft", "paddingRight"로 나누어 사용합니다.

<LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#FFFFFF">

        <ImageView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="30dp"
            android:layout_marginBottom="40dp"
            android:paddingLeft="10dp"
            android:paddingTop="20dp"
            android:paddingRight="30dp"
            android:paddingBottom="40dp"
            android:background="#AAAAAA"
            android:src="@drawable/android_logo" />

    </LinearLayout>

Layout Margin and Padding Example 2


2.3 Layout 내의 View 위젯의 위치 정렬. (layout_gravity)

Layout에 자식 View 위젯이 배치되면, 기본적으로 좌측 상단에 표시됩니다. 즉, Layout에 위치 정렬과 관련된 어떠한 속성도 사용되지 않은 경우, 기본적인 정렬 방향이 수평(horizontal) 방향으로 왼쪽에, 수직(vertical) 방향으로 위쪽이 된다는 것이죠.

Layout gravity 기본 값. (Left, Top)


"layout_gravity" 속성을 사용하면, Layout 내에서 자식 View 위젯이 정렬되는 위치를 바꿀 수 있습니다.

  * android:layout_gravity - 자신이 속한 부모 Layout내 자신의 정렬 위치 값 지정.
        > 부모 Layout 내에서 x축(좌/우)과 y축(상/하)을 기준으로 정렬.
        > 아래 값들 중에서 하나 이상의 값을 '|' 기호로 혼합하여 사용.
          -. top (0x30)               : 부모 Layout 안에서, 위쪽에 위치.
          -. bottom (0x50)            : 부모 Layout 안에서, 아래쪽에 위치.
          -. left (0x03)              : 부모 Layout 안에서, 왼쪽에 위치.
          -. right (0x05)             : 부모 Layout 안에서, 오른쪽에 위치.
          -. center_vertical (0x10)   : 세로 기준으로 가운데 위치.
          -. fill_vertical (0x70)     : 세로 방향으로 가득 채움.
          -. center_horizontal (0x01) : 가로 기준으로 가운데 위치.
          -. fill_horizontal (0x07)   : 가로 방향으로 가득 채움.
          -. center (0x11)            : 가로, 세로 기준으로 가운데 정렬.
          -. fill (0x77)              : 가로, 세로 방향으로 가득 채움.
          -. clip_vertical (0x80)     : 세로 기준으로 Layout을 넘어서는 영역 자르기.
          -. clip_horizontal (0x08)   : 가로 기준으로 Layout를 넘어서는 영역 자르기.
          -. start (0x00800003)       : 부모 Layout 안에서, 시작 위치에 정렬.
          -. end (0x00800005)         : 부모 Layout 안에서, 끝 위치에 정렬.
        > 부모 Layout이 RelativeLayout인 경우, 적용되지 않음.

아래는 LinearLayout에서 자식(Children) TextView의 layout_gravity 속성에 각각 "left", "right", "center_horizontal", "fill_horizontal", "clip_horizontal", "start", "end" 값을 사용한 결과입니다. 즉, 가로(horizontal) 방향 정렬과 관련된 값을 적용한 예제입니다.

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF0000"
            android:textSize="20sp"
            android:layout_gravity="left"
            android:text="left" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00FF00"
            android:textSize="20sp"
            android:layout_gravity="right"
            android:text="right" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#0000FF"
            android:textColor="#FFFFFF"
            android:textSize="20sp"
            android:layout_gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFFF00"
            android:textSize="20sp"
            android:layout_gravity="fill_horizontal"
            android:text="fill_horizontal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF00FF"
            android:textSize="20sp"
            android:layout_gravity="clip_horizontal"
            android:text="clip_horizontal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00FFFF"
            android:textSize="20sp"
            android:layout_gravity="start"
            android:text="start" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#000000"
            android:textColor="#FFFFFF"
            android:textSize="20sp"
            android:layout_gravity="end"
            android:text="end" />

    </LinearLayout>

가로(horizontal) 방향 정렬 예제


다음은 layout_gravity 속성에 각각 "top", "bottom", "center_vertical", "fill_vertical", "clip_vertical" 값을 사용한 결과입니다. 즉, 세로(vertical) 방향 정렬과 관련된 값을 적용한 예제입니다.

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF0000"
            android:textSize="20sp"
            android:layout_gravity="top"
            android:text="top" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00FF00"
            android:textSize="20sp"
            android:layout_gravity="bottom"
            android:text="bottom" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#0000FF"
            android:textColor="#FFFFFF"
            android:textSize="20sp"
            android:layout_gravity="center_vertical"
            android:text="center_vertical" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFFF00"
            android:textSize="20sp"
            android:layout_gravity="fill_vertical"
            android:text="fill_vertical" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF00FF"
            android:textSize="20sp"
            android:layout_gravity="clip_vertical"
            android:text="clip_vertical" />
    </LinearLayout>

세로(vertical) 방향 정렬 예제


아래 예제는 layout_gravity 속성에 "center" 값을 지정한 결과입니다. "center" 속성은 가로(horizontal), 세로(vertical) 방향을 기준으로 가운데 정렬을 위한 속성이므로 "center_horizontal|center_vertical"을 지정한 것과 같은 결과를 표시합니다. 또한 아래 예제에서는 정확한 결과 확인을 위해 LinearLayout 대신 FrameLayout을 사용하였습니다.

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#000000"
            android:textColor="#FFFFFF"
            android:textSize="20sp"
            android:layout_gravity="center"
            android:text="center" />

    </FrameLayout>

layout_gravity center 예제


2.3.1 "layout_gravity" 속성과 "gravity" 속성

Layout 요소에 사용할 수 있는 정렬 관련 속성은 "layout_gravity"와 "gravity", 두 가지가 있습니다. 이름이 비슷하여 사용 방법이 혼동될 수 있지만, 이 글의 초반에 간단히 언급했던 "layout_"으로 시작하는 속성의 특징을 되짚어보면, 쉽게 구분할 수 있을 것입니다.


"layout_gravity" 속성은 앞서 설명한대로, 부모 Layout 내에서 View가 정렬되는 위치를 결정하는 속성입니다. 반면, "gravity" 속성은 부모 Layout과는 관계없이, View 위젯 내에 표시되는 내용이 정렬되는 위치를 정하기 위한 속성입니다. 즉, TextView를 예로 들자면, TextView 위젯 안에 표시되는 텍스트가 TextView 내에서 어디에 정렬될 것인가를 지정하기 위한 속성이 바로 "gravity" 속성인 것입니다.

layout_gravity와 gravity의 차이점



아래는 layout_gravity와 gravity 속성을 사용하여 TextView와 텍스트의 정렬 결과를 확인할 수 있는 예제 소스 코드입니다. 차이점 구분을 보다 명확하게 확인하기 위해, 각 요소의 크기(width, height) 값에 고정 크기를 지정한 것을 주의하세요.

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#00FF00">

        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#0000FF"
            android:textColor="#FFFFFF"
            android:layout_gravity="center"
            android:gravity="left|center_vertical"
            android:text="TEXT"/>

    </FrameLayout>

layout_gravity와 gravity의 차이점 예제


2.3.2 Layout의 "gravity" 속성과 자식(Children) View 위젯의 "layout_gravity" 속성의 충돌.

앞서 설명한대로 gravity 속성은 자신이 표현하는 내용의 정렬 기준을 설정하기 위한 속성입니다. 반면 layout_gravity 속성은 부모 Layout 내에서 자신의 정렬 기준을 요청하기 위한 속성이죠.


그럼 만약, 부모 Layout에서 gravity 속성에 "right" 값을 지정하여 자식(Children) View 위젯을 오른쪽에 정렬하려고 하고, 자식(Children) View 위젯에서는 layout_gravity 속성에 "left" 값을 지정하여 왼쪽에 정렬되려고 하면 어떤 결과가 나오게 될까요?

부모의 gravity와 자식의 layout_gravity 우선순위


예제 코드를 통해, 결과를 직접 확인해보죠.

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF0000"
            android:textSize="30sp"
            android:text="none" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00FF00"
            android:textSize="30sp"
            android:layout_gravity="left"
            android:text="left" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#0000FF"
            android:textColor="#FFFFFF"
            android:textSize="30sp"
            android:layout_gravity="center"
            android:text="center" />

    </LinearLayout>

부모의 gravity와 자식의 layout_gravity 우선순위 예제


표시되는 결과를 보면, 부모 Layout의 gravity 속성이 아닌, 자식 View 위젯의 layout_gravity 속성이 적용되는 것을 확인할 수 있습니다. 하지만 layout_gravity를 사용하지 않은 "none" TextView의 경우, 부모 Layout의 gravity 속성을 따릅니다.


결과적으로 부모의 gravity 속성이 먼저 적용된 다음, 자식의 layout_gravity가 적용되어 정렬 결과를 덮어쓰게 되는 것입니다.

3. 참고.

.END.


ANDROID 프로그래밍/LAYOUT , , , , , , , , ,

  1. Blog Icon
    Thanks

    좋은 글 감사드립니다
    Margin, Padding, Gravity 관련해서 한 눈에 잘 들어오게 설명해 주신것 같습니다

  2. 나름 열심히 정리한다고 했는데, 그래도 많이 부족하네요. 그럼에도 격려 글 남겨주셔서 감사드립니다.

  3. Blog Icon
    chrono

    항상 잘 보고 있습니다.

  4. 감사합니다.
    더 좋은 내용 작성하도록 노력할게요. ^^

  5. Blog Icon
    와우

    정말 감사합니다! 많은도움이 됐어요

  6. 방문해 주셔서 감사드립니다.

  7. Blog Icon
    감사감사

    예제와 좋은 설명 감사합니다!!

  8. 칭찬글 남겨주셔서 감사드립니다!!

  9. Blog Icon
    CaptainHaneum

    와~ 그림 설명으로 개념이 이해가 되었습니다. 너무 감사합니다.

  10. 도움이 되신 것 같아 다행입니다.

    방문해 주셔서 감사합니다.

  11. Blog Icon
    아흐 너무 감사하자녀

    말도안되는 명강의 ㅜㅜ
    돈내고 듣는거보다 100배 훌륭합니다~~

  12. 딱.. 찾으시던 내용이셨나보네요.
    칭찬글 남겨주셔서 감사합니다.

  13. 잘봤습니다 감사합니다!

  14. 방문해 주셔서 감사합니다.

  15. Blog Icon

    비밀댓글입니다

  16. 관심깊게 봐주셔서 감사합니다.
    내용 검수자 없이 혼자서 작성하다보니,
    가끔 잘못된 내용이 들어가는 경우가 있네요.

    관련 내용은 확인해서 반영하겠습니다.

    감사합니다.

  17. Blog Icon
    rigondo

    컴공 전공하는 대학생인데 이제 안드로이드 배우면서 좀 어려웠는데...형님 감사합니다. 복 받으세요

  18. 도움이 되신 것 같아서 다행입니다.
    포기하지 마시고, 열심히 공부하셔서!!!
    공무원 되세요!!!

  19. Blog Icon
    쪼꼬미

    안드로이드 업무가 갑자기 생겨서 코딩중 레이아웃에 부딪혔는데 많은 도움됬어요 감사합니다.

  20. 모바일 UI 개발에 익숙하지 않으면, 레이아웃에 대한 개념이 쉽게 와닿지 않을 수 있죠.

    그래도 도움이 되셨다니 다행입니다.

    업무 진행 중에 도움이 필요한 내용이 있으면 언제든 질문글 남겨주세요.
    최대한 도움 드릴 수 있도록 노력하겠습니다.

    감사합니다.

  21. Blog Icon
    감사합니다

    선생님 항상 감사드립니다. 많은 도움이 됩니다.

  22. 방문해 주셔서 감사합니다.

  23. Blog Icon
    hyeon

    안녕하세요 선생님
    정말 좋은 글 감사합니다.덕분에 안드로이드 처음부터 배우고 있습니다.
    헌데 여쭤볼게 3개정도 있습니다..ㅠㅠ

    첫번째는, 윗 예제중 가로 정렬이라 하셨는데 왜
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    부분에서 vertical인지요,horizontal값이여야 하는 것 아닌가요?

    또한 세로(vertical) 방향 정렬일시에도

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

    왜 horizontal값인가요??원래는 vertical값이여야 하는것 아닌지요,ㅠㅠ

    세번째 질문은 세로방향 정렬시
    결과값 중,

    left
    ____centervertical
    __bottom

    왜 bottom부분이 left 가로 값만큼 떨어져서 나오나요??
    또한 왜 center는 bottom가로 값만큼의 여백을 갖지않고,무슨 기준으로 저기에 어중간하게 위치해있는가요??ㅠㅠ;;


    left___________fill clip

    fill, clip또한 왜 left바로 옆에 붙지않나요??

    세로정렬이면
    left

    fill
    center_vertical
    clip


    bottom

    이렇게 나와야하는것 아닌가요???
    (공백없이)


    가로방향정렬에는
    left__________|
    _____________right
    _____center_horizontal
    fill
    clip
    start_________________
    _____________________end

    각각 block이니까 그 높이만큼 높이여백을 가진다는 건 알겠어요..

    근데 vertical은 왜그런지,
    가로정렬인데 왜 orentation은
    vertical인지(서로 반대인지)

    혼란스럽습니다...ㅠㅠㅠㅠ

    질문이 많았네요..좀 더 찾아보겠습니다..ㅠㅠ

  24. 본문의 내용을 조금 더 정확하게 파악하셔야 합니다.

    질문 글을 보면, LinearLayout의 orientation의 의미는 정확히 알고 있으신 것 같은데요.

    본문의 내용에서 설명하는 내용은 단순히 LinearLayout의 정렬 방향이 아닙니다. 즉, LinearLayout의 orientation 속성에 대한 설명을 하는 게 아니라는 것이죠.

    본문의 예제는 gravity를 설명하는 내용입니다.
    그러니 정렬 이라고 하는 게, orientation 속성을 말하는 게 아니고, layout_gravity를 말하는 것이지요.

    일단 예제를 직접 작성해서 실행해보시고, 값을 바꿔보세요.

    그러면 조금 더 쉽게 이해하실 수 있을거라 생각합니다.

    감사합니다.