태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

네 자리는 내가 결정한다 - 레이아웃(Layout)

2010.01.21 14:56

안드로이드의 화면을 구성하는 요소는 크게 레이아웃(Layout)과 위젯(Widget)으로 나눌 수 있습니다. 

위젯은 텍트스를 표시해주는 TextView, 그림을 표시해주는 ImageView, 버튼, EditText, RadioButton, CheckBox 등 사용자의 입력을 받거나 화면에 데이터를 표시해주는 것들이며, 레이아웃은 이러한 위젯들을 어떠한 방식으로 화면에 배치해줄지를 결정해주는 하나의 "컨테이너" 역할을 합니다.

레이아웃에 포함되는 위젯들은 하나의 뷰(View)를 상속받은 것들이며, 결국 레이아웃은 뷰들을 담을 수 있는 객체라 할 수 있습니다. 따라서, 레이아웃을 ViewGroup이라고도 합니다. (실제로 다른 뷰를 담을 수 있는 객체들은 ViewGroup을 상속하고 있습니다.)

일반적인 윈도우 어플리케이션 등에서 레이아웃을 짤 때는 주로 각각의 구성요소를 마우스로 끌어서 원하는 위치에 놓는 방식으로 화면을 구성하는데, 안드로이드는 자바의 Swing어플리케이션의 레이아웃을 짤 때 처럼 절대적인 위치를 지정하기 보다는 일정한 규칙에 의해서 각각의 구성요소를 배치하는 방식을 주로 사용합니다. (물론, 절대적인 위치를 지정하는 레이아웃도 있기는 하다만, 자주 쓰이지는 않습니다)

자, 그럼 슬슬 안드로이드의 레이아웃에 대해 하나씩 알아보도록 하겠습니다.

1. LinearLayout

가장 기본적이면서도 가장 많이 사용되는 레이아웃입니다. 레이아웃 내의 요소들을 수직, 수평으로 배치합니다.
배치 방향을 결정하는 속성은 orientation으로, vertical로 설정시 레이아웃 내의 요소들을 수직으로, horizontal로 설정시 수평으로 배치하게 됩니다.

orientation="vertical" 일 경우
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<EditText android:text="EditText" 
	android:id="@+id/EditText01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>

<Button android:text="Button" 
	android:id="@+id/Button01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>
	
</LinearLayout>

수직 방향으로 요소들이 배치된 모습



orientation="horizontal" 일 경우
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<EditText android:text="EditText" 
	android:id="@+id/EditText01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>

<Button android:text="Button" 
	android:id="@+id/Button01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>
	
</LinearLayout>

수평 방향으로 요소들이 배치된 모습




2. RelativeLayout

RelativeLayout은 레이아웃 내의 요소들간에 위치관계를 부여하고, 그 관계에 따라 화면을 구성합니다. RelativeLayout도 LinearLayout만큼 많이 쓰이는 레이아웃이며, LinearLayout에 비해 각 요소의 위치를 조금 더 세밀하게 조정하는 것이 가능하기에 복잡한 화면을 구성할 때 주로 쓰입니다.

RelativeLayout은 LinearLayout처럼 레이아웃 자체에서 지정해주는 속성은 따로 없으며, 레이아웃 내의 요소들이 가지는 속성에 따라 각 요소의 위치가 결정됩니다. 아래에 RelativeLayout 내의 요소들이 가질 수 있는 속성들을 정리해 보았습니다.

레이아웃 내 요소들간의 관계를 지정하는 속성
  • Layout above : 해당 요소가 이곳에 지정한 ID를 가지는 요소의 바로 위에 위치하도록 합니다.
  • Layout below : 해당 요소가 이곳에 지정한 ID를 가지는 요소의 바로 아래에 위치하도록 합니다.
  • Layout to left of : 해당 요소가 이곳에 지정한 ID를 가지는 요소의 바로 왼쪽에 위치하도록 합니다.
  • Layout to right of : 해당 요소가 이곳에 지정한 ID를 가지는 요소의 바로 오른쪽에 위치하도록 합니다.
  • Layout align left : 해당 요소의 왼쪽 끝선을 이곳에 지정한 ID를 가지는 요소의 왼쪽 끝선과 일치시킵니다.
  • Layout align right : 해당 요소의 오른쪽 끝선을 이곳에 지정한 ID를 가지는 요소의 오른쪽 끝선과 일치시킵니다.
  • Layout align top : 해당 요소의 윗선을 이곳에 지정한 ID를 가지는 요소의 윗선과 일치시킵니다.
  • Layout align bottom : 해당 요소의 아랫선을 이곳에 지정한 ID를 가지는 요소의 아랫선과 일치시킵니다.

레이아웃과 요소간의 관계를 지정하는 속성
  • Layout align parent left : 해당 요소의 왼쪽 끝선을 parent(레이아웃)의 왼쪽 끝과 일치시킵니다.
  • Layout align parent right : 해당 요소의 오른쪽 끝선을 레이아웃의 오른쪽 끝과 일치시킵니다.
  • Layout align parent top : 해당 요소의 윗선을 레이아웃의 윗선과 일치시킵니다.
  • Layout align parent bottom : 해당 요소의 아랫선을 레이아웃의 아랫선과 일치시킵니다.

RelativeLayout은 각 요소들의 위치를 세밀하게 지정할 수 있기에, 이처럼 속성들이 좀 많습니다. 하지만 이 속성들만 이해한다면 얼마든지 복잡한 레이아웃도 만들 수 있으니 잘 알아두도록 하세요. 아래는 RelativeLayout을 이용하여 레이아웃을 구성한 예입니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<EditText android:text="EditText" 
	android:id="@+id/EditText01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:layout_alignParentRight="true"/>

<Button android:text="Button" 
	android:id="@+id/Button01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:layout_toLeftOf="@+id/EditText01" 
	android:layout_below="@+id/EditText01"/>
	
</RelativeLayout>

EditText는 레이아웃 오른쪽에 위치하도록, Button은 EditText의 왼쪽 아래에 위치하도록 지정한 모습





3. FrameLayout

FrameLayout은 각 요소들을 모두 왼쪽 상단을 기준으로 포개는 방식으로 배치합니다. 주로 탭(Tab)을 이용할 때 자주 사용됩니다. 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<EditText android:text="EditText" 
	android:id="@+id/EditText01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	/>

<Button android:text="Button" 
	android:id="@+id/Button01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	/>
	
</FrameLayout>

FrameLayout의 배치 모습. 각 요소들이 왼쪽 상단을 기준으로 겹쳐져 배치된 것을 확인할 수 있습니다.



4. AbsoluteLayout (Deprecated)

AbsoluteLayout은 그 이름에서도 알 수 있듯이 레이아웃 내의 요소이 배치될 "절대적인" 위치를 지정해주는 레이아웃입니다. 따라서, Portrait 모드에서 보이던 요소가 Landscape 모드에서는 화면에 보이지 않게 될 수 있습니다. 이 레이아웃은 현재 Deprecated 상태로, 가급적 사용하지 않는 것이 좋습니다.

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    android:layout_y="0px" android:layout_x="0px"/>
<EditText android:text="EditText" 
	android:id="@+id/EditText01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:layout_x="100px" android:layout_y="300px"/>

<Button android:text="Button" 
	android:id="@+id/Button01" 
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content" 
	android:layout_x="30px" android:layout_y="30px"/>
	
</AbsoluteLayout>

Portrait 모드일 때의 모습. 모든 요소가 화면에 표시되고 있습니다.



Landscape 모드일 때의 화면. EditText의 위치가 x=100px, y=300px 이므로 이 모드에서는 보이지 않습니다.



5. TableLayout

TableLayout 또한 이름에서 알 수 있듯이 표 형태의 레이아웃을 제공합니다. 일정한 선에 맞추어 정렬되어야 하는 요소 (다이얼 버튼 등)를 정렬 할 때 주로 사용합니다.

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TableRow
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content">
		
		<TextView  
		    android:layout_width="wrap_content" 
		    android:layout_height="wrap_content" 
		    android:text="Text" />
		
		<EditText android:text="EditText" 
			android:id="@+id/EditText01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
			
	</TableRow>
	
	<TableRow
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content">

		<Button android:text="Button" 
			android:id="@+id/Button01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
			
		<Button android:text="Button" 
			android:id="@+id/Button02" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
		
	</TableRow>
</TableLayout>
행의 구분은 TableRow 태그로 구분하며, 각 열의 너비는 그 열 안의 요소들의 너비에 따라 결정됩니다. 위에서는 열의 너비를 각각이 최소로 가지는 크기 (wrap_content)가 되도록 지정하였습니다.



6. ScrollView

한 화면에 표시해야 할 내용이 많을 경우 사용합니다. 리스트에서 내용이 많아지면 스크롤바가 생기는 것처럼, ScrollView 내에의 요소들이 한 화면에 표시되기 어려울 만큼 공간을 많이 차지한다면 스크롤바를 표시하여 스크롤을 통해 한 화면에 표시되지 않는 요소를 볼 수 있게 해줍니다.

ScrollView는 단 하나의 요소만을 포함할 수 있으므로, ScrollView에 요소들을 넣기 전에 해당 요소들은 모드 LinearLayout이나 RelativeLayout 등의 레이아웃에 미리 포함시켜 놓고, 그 레이아웃이 ScrollView의 하위 요소로 포함되도록 구성하여야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    
    <LinearLayout
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	android:orientation="vertical">
		
		<TextView  
		    android:layout_width="wrap_content" 
		    android:layout_height="wrap_content" 
		    android:text="Text" />
		
		<EditText android:text="EditText" 
			android:id="@+id/EditText01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
		
		<Button android:text="Button" 
			android:id="@+id/Button01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
			
		<Button android:text="Button" 
			android:id="@+id/Button02" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
		
		<ToggleButton android:id="@+id/ToggleButton01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content" />
		
		<DatePicker android:id="@+id/DatePicker01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content"/>
		
		<TimePicker android:id="@+id/TimePicker01" 
			android:layout_width="wrap_content" 
			android:layout_height="wrap_content"/>
			
	</LinearLayout>

</ScrollView>

화면 오른쪽에 스크롤바가 생긴 것을 확인할 수 있습니다.


저작자 표시 비영리 변경 금지
신고

커니 유저 인터페이스/레이아웃(Layout) , , , , ,

  1. Blog Icon
    초보

    안그래도 이 부분 공부 하고 있었는데 잘 정리해주셨네요 잘 보고 갑니다^^

  2. Blog Icon
    dduksun2

    커니님... 너무 초보적인 질문인가요???

    커니님 강의를 너무 잘 보고 있습니다.
    그래서 저에게 중요하고, 또 자주 사용할것 같은 내용들을 제 블로그에 퍼가려고 하는데요
    주소복사하기 버튼으로 복사를 해서 링크를 걸었는데
    그 링크를 클릭하면 제가 원하는 페이지가 자동으로 표시되지 않네요...
    블로그를 잘 사용하지 않아서 제가 모르는건지.... ㅠㅠ

    다른 블로그들은 잘 되는것 같은데 커니님 블로그만 안되는것 같아서요
    왜 안될까요~ 알려주세요~!

  3. 정확히 어떤걸 말씀하시는지 잘 모르겠습니다 ^^;;
    링크를 클릭해도 제데로 표시되지 않는다는 말씀이신가요?

    제 블로그에 그런 차단장치(?)는 없습니다 ㅎㅎ;;

  4. Blog Icon
    dduksun2

    예를 들어 지금 이 글의 TRACKBACK 의 복사 버튼을 눌러서 주소창에 붙여 넣으면요...


    <?xml version="1.0" encoding="utf-8" ?>
    - <response>
    - <error>
    - <![CDATA[ 1
    ]]>
    </error>
    - <message>
    - <![CDATA[ URL does not exist(5)
    ]]>
    </message>
    </response>

    화면에 이렇게 나타나거든요.... 저만 그런가요 ^^;;

  5. 제가 해봤을땐 문제가 없는데...
    다른 PC에서도 그러나요??

  6. Blog Icon
    dduksun2

    피씨 두대에서... 확인해봤는뎅...
    왜그럴까요... ㅠㅠ

  7. 아... 트랙백 주소를 그냥 주소창에 붙여넣으셨네요.

    트랙백 주소는 이 글의 주소가 아니랍니다~
    이 글의 주손는 htto://androidhuman.tistory.com/숫자 요런식이에요 ㅎㅎ

    이 글의 번호가 332번이니 요 글을 링크하시려면 http://androidhuman.tistory.com/332 를 입력해주시면 됩니다.

  8. Blog Icon
    DarkLTH

    제가 알고 싶어 하던 내용들이네요. ~ 워낙 초보다 보니 버튼 위치 바꾸는것도 쉽지가 않았는데.
    감사합니다.

  9. Blog Icon
    osh

    저기 .. adove 가아니라 above 네요 ㅠㅠ adove 로했다가 에러 고치느라 ^^; 잘보고있어요~

  10. 수정하였습니다^^
    제보 감사합니다 :)

  11. Blog Icon

    와우!! 좋은 자료 감사합니다!! ㅎ
    저 질문하나만요 ㅠ
    라디오 버튼 사용시 라디오 그룹으로 묶으면
    자리 지정은 어떻게 해야 되나요??
    지정이 안먹는데..ㅠㅠ

  12. 라디오버튼을 감싸는 RadioGroup은 LinearLayout과 유사한 속성을 가지고 있으므로, 버튼들을 가로 혹은 세로방향으로 배치합니다.

    orientation속성으로 지정하시면 됩니다 :)

  13. Blog Icon
    M.Ali

    안녕하세요 커니님

    커니님 도서 주문하고 기다리는동안 계속 블로그 들락거리면서 공부하고있는 학생입니다;;

    예제에서 보여주셨던 DatePicker와 TimePicker에 궁금한점이 있어서 여쭤볼까합니다

    저 두 피커에서 설정한 시각을 가지고 알람을 만들어볼려고 하는데요

    저 두피커 값이 저장되는 곳이 어딘지 궁금해요 ㅠㅠ

    아직 자바도 초보구 자바 하면서 안드로이드를 병행하고 있어서 아직 많이 부족합니다 ㅠ

    답변부탁드립니다.

  14. Blog Icon
    브라이언

    <FrameLayout android:layout_height="wrap_content"
    android:background="@drawable/noti_edit_btn_3"
    android:layout_marginLeft="7dip" android:layout_width="wrap_content"
    android:orientation="horizontal">
    <ImageView android:id="@+id/ImageView07"
    android:layout_height="wrap_content" android:src="@drawable/noti_edit_ringtons"
    android:layout_width="fill_parent" android:layout_gravity="center_vertical" android:layout_marginLeft="13dip" />
    <FrameLayout android:id="@+id/FrameLayout01"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:layout_marginTop="6dip" android:layout_marginLeft="215dp">
    <ImageButton android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:background="@drawable/selector_rington_btn"
    android:id="@+id/rain_rington_btn" />
    <ImageView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:layout_gravity="center_vertical|center_horizontal"
    android:id="@+id/rain_rington_img" android:background="@drawable/ringtone_on" />
    </FrameLayout>
    </FrameLayout>

    영문 버전으로 돌리면 이상 없이 배치가 되는데요..
    한글 버전으로 돌리면 겹쳐지게 되더라구요..
    자바 코드에서 좌표를 따로 잡거나 하진 않습니다...
    원인이 뭔지 알수가 없습니다..

    도와주세요..ㅠ.ㅠ

  15. layout-ko 등의 폴더에 똑같은 리소스를 저장했는지 확인해보세요. Alternative Resource를 사용할 때 여러 리소스 모두를 수정하지 않아 이러한 문제가 발생할 수 있습니다.

  16. Blog Icon
    바둥이

    제 네이버 블로그에 퍼가도 되나요?

  17. 넵~ 출처 표시만 해주세요!

  18. Blog Icon
    angkeloss

    좋은 정보 잘 보고 갑니다.~
    출처 밝히고 담아 갑니다.!!