레이아웃 (Layout) 안드로이드프로그래밍정복 (Android Programming Complete Guide)
Contents v 학습목표 뷰와레이아웃에대해이해하고, 레이아웃을활용, 관리하는여러가지기법들에대하여알아본다. v 내용 뷰 (View) 리니어레이아웃 (Linear Layout)
v 뷰의계층 안드로이드응용프로그램의화면을구성하는주요단위인액티비티는화면에직접적으로보이지않으며, 액티비티안의뷰가사용자를대면하는실체 여러개의뷰가모여하나의액티비티를구성하고, 이러한액티비티가모여하나의응용프로그램 레이아웃은액티비티안에뷰를배치하는기법 뷰 위젯 : 직접적으로보이며사용자인터페이스를구성하며, 흔히컨트롤이라부름 뷰그룹 : 뷰를담는컨테이너역할을하며, 이부류의클래스들을레이아웃이라함 뷰그룹이면서도위젯처럼사용되기도하는클래스도있으며, 특정위젯을상세히알고싶다면그슈퍼클래스들부터연구해야함 서브클래스는슈퍼클래스의모든속성을상속받음
v 뷰의계층 View 도자바클래스의일종이므로루트인 Object 로부터파생 View 로부터직접파생되는모든클래스가바로위젯이며스스로를그릴수있는능력을가짐 Object AnalogClock EditText AutoCompleteTextView View TextView Button CompoundButton Chronometer CheckBox DigitalClock RadioButton ImageView ImageButton ToggleButton SurfaceView GLSurfaceView VideoView SeekBar ProgressBar AbsSeekBar RatingBar
v 뷰의계층 View 로부터파생된 ViewGroup 의서브클래스 다른뷰들을차일드로포함하며차일드를정렬하는기능을가짐 Object View FrameLayout ScrollView, HorizontalScrollView TabHost, TimePicker, DatePicker ViewGroup AbsoluteLayout ViewAnimator WebView ViewFlipper ViewSwitcher TextSwitcher ImageSwitcher RelativeLayout LinearLayout RadioGroup, ZoomControls TableLayout, TableRow TabWidget AdapterView AbsListView AbsSpinner ListView GridView Spinner Gallery
v View 의속성 id 뷰를칭하는이름을정의하며, 코드나 XML 문서에서뷰를참조할때 id 를사용하므로직관적인이름을붙이는것이좋음 형식 : @[+]id/id - @ : id 를리소스 (R.java) 에정의하거나참조한다는뜻이며, 무조건붙여야함 - + : ID 를새로정의한다는뜻이며, 참조시는생략가능 - id : 예약어 - / : 뒤에원하는이름을작성하되, ID 는고유한명칭이므로명령규칙에맞아야하며, 뷰끼리중복되어서는안됨 ex) android:id= @+id/name : 텍스트뷰에 name 이라는 id 를부여함. XML 문서에 ID 를지정하면이이름이 R.java 에정수형상수로정의 코드에서뷰를참조할시 findviewbyid 메서드호출, 인수로참조할뷰의 id 를전달 모든뷰에 id 를의무적으로지정할필요는없으며, 코드에서참조할필요없는위젯은보통 id 를생략
v View 의속성 layout_width, layout_height 뷰의폭과높이를지정하며, 수평, 수직각방향에대해크기를지정가능 속성값으로아래의세가지중하나의값을가짐 - fill_parent : 부모의주어진크기를다채움 - wrap_content : 내용물의크기만큼만채움. - 정수크기 : 지정한크기에맞춤 ex) Start 라는캡션을가지는버튼배치 지정한크기가액면대로다받아들여지지않으며, 주위다른위젯들의크기에영향을받음 명시적인크기지정시정수하나와단위를지정하는예약어를같이사용하며, 이이단위는크기를지정하는모든속성에공통적으로적용 단위 : px, in, mm, pt, dp ( 또는 dip), sp ( 또는 sip)
v View 의속성 background 뷰의배경을지정하며, 색상및이미지등의여러가지객체로지정가능 색상지정시네가지형식이적용되며, 배경뿐만아니라색상을지정하는모든속성에적용 - #RGB - #ARGB - #RRGGBB - #AARRGGBB ex) #ff0000 (#f00) : 빨간색, #0000ff (#00f) : 파란색 padding 뷰와내용물간의간격을지정 ( 즉안쪽여백 ) padding 속성값을지정하여 4방향에대한여백을조절 속성값 : paddingleft, paddingtop, paddingright, paddingbottom
v View 의속성 visibility 뷰의표시유무를지정하며, 속성값으로아래의세가지중하나의값을가짐 - visible : 보이는상태임. - invisible : 숨겨진상태이되자리는차지함. - gone : 숨겨지며자리도차지하지않음. clickable, longclickable 마우스클릭이벤트를받을것인지, 롱클릭이벤트를받을것인지를지정 - click : 손가락으로뷰를누름 - longclick: 손가락으로뷰를누른채잠시기다림 진위형이므로 true 또는 false 둘중하나의값을지정 focusable 키보드포커스를받을수있는지를지정 디폴트값으로 false가설정되어있으며, 필요시속성을 true로변경 에디트나버튼처럼사용자의입력이필요한파생클래스는디폴트로 true가지정
v TextView 문자열출력및입력받는위젯 입력기능은숨겨져있으며서브클래스인 EditText 에서활성화
v TextView text 텍스트뷰의가장중요한속성으로출력할문자열을지정 리터널및리소스로대입 문자열 형식 @[ 패키지 :]type:name 설명 겹따옴표로문자열을싸서바로대입한다. \ 문자가들어가면이스케이프된다. \n 은개행이며 \uxxxxx 는유니코드문자이다. 리소스에대한레퍼런스로지정한다. 보통 string.xml 에문자열을정의해놓고 @string/id 식으로지정한다.?[ 패키지 :][type:]name 테마속성으로지정한다. textcolor 문자열의색상을지정하며, 디폴트는불투명한밝은회색 #RRGGBB 나 #AARRGGBB 형식으로각색상요소들의강도를지정
v TextView textsize 텍스트의폰트크기를지정하며, 실수타입으로지정할때숫자뒤에 sp, dp, px, in, mm 등의단위를같이지정 textstyle 폰트의속성을지정 normal, bold, italic 중하나를쓰거나 로묶어두개이상의상수값을지정가능 ex: bold italic, normal italic typeface 글꼴의모양을지정하며, normal, sans, serif, monospace 중하나로선택가능 모바일환경에서내장된폰트개수에제약이있음 width, height 텍스트뷰의폭과높이이며크기값과단위를같이지정 텍스트뷰는단독으로존재하는경우는거의없고대부분레이아웃안에서차일드로존재하기때문에이두속성은거의사용되지않음
v TextView singleline 텍스트가위젯의폭보다길때강제로한줄에출력 속성의디폴트는 false 로폭보다더긴줄은자동으로아래쪽으로개행 [ TextView 예제실행결과 ] string.xml <?xml version= 1.0 encoding= utf-8 > <resources> <string name= hello >Hello World, TextViewTest!</string> <string name= app_name >TextViewTest</string> <string name= insa >Hello</string> <string name= anyoung > 안녕하세요 </string> </resources> main.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <TextView android:text= @string/insa android:textcolor= #ff0000 android:textsize= 20pt android:textstyle= italic /> <TextView android:text= @string/anyoung android:textsize= 20sp android:background= @0000ff /> <TextView android:text= Good Morning android:textcolor= #8000ff00 android:textsize= 5mm android:typeface= serif /> </LinearLayout>
v 배포예제 온라인배포페이지에서업데이트된최신예제제공 http://www.winapi.co.kr/android 모든예제가하나의통합프로젝트안에포함되어있음 (AndExam 프로젝트 ) File/Import 명령 AndExam 프로젝트 임포트통합예제를워크스페이스에설치 상단의스피너에서장번호선택시해당장의예제목록이리스트에나타남
v 배포예제 모든예제는통합예제의패키지명인 exam.andexam에작성됨 개별예제로배포시폰에설치할수없음 설치가능하더라도무수히많은예제중원하는예제를찾는것이힘듬 각예제마다고유한이름을붙이는것이거의불가능함 장별로접두를붙여놓아명칭충돌문제를해결하고프로젝트탐색기에장별로소스정렬
v ImageView 아이콘이나비트맵을출력하는위젯으로, 리소스, 파일등은물론이고컨텐트프로바이더나웹상의이미지로도표시가능 src 출력할이미지를지정하는가장중요한속성 주로리소스에이미지를복사해두고 @drawable/id 형식으로이미지를출력하는방법을사용 maxheight, maxwidth 이미지가출력될최대크기를지정 adjustviewbounds 이미지의종횡비를맞추기위해이미지뷰의크기를적당히조정할것인가를지정하며, 속성값은 true 나 false 중하나를사용 그외 croptopadding, tint, scaletype
v ImageView jpg, png, gif 등의이미지포맷을지원 SDK 1.6 이후밀도별로세개의폴더가존재하며, 해상도별로각폴더에이미지를넣어두면운영체제가사용할이미지를결정 고해상도이미지 저해상도이미지 중해상도이미지 c03_imageviewtest.xml [ ImageView 예제실행결과 ] <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <ImageView android:src= @drawable/pride /> <ImageView android:src= @drawable/pride android:maxheight= 70px android:maxwidth= 120px android:adjustviewbounds= true /> <ImageView android:src= @drawable/dog android:tint= #4000ff00 /> </LinearLayout>
v 버튼과에디트 View, TextView 의서브클래스이며고유의속성은따로가지지않음 Button : 사용자로부터명령을입력받음 EditText : 문자열을입력받음 ( 에디트 ) c03_buttonedit.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <EditText android:layout_width= wrap_content android:id= @+id/edit android:text= 여기다입력 /> <Button android:layout_width= wrap_content android:id= @+id/btn android:text= 입력완료 /> </LinearLayout>
v 버튼과에디트 SDK 2.3( 진저브레드 ) 에서에디트의입력기능개선 입력하는위치아래쪽에나타나는오각형모양의마커를드래그하면입력위치를옮길수있음 에디트를롱프레스하면팝업메뉴가나타나고, Select word 명령선택시현재단어가선택됨 선택영역좌우의사각형마커를드래그하여선택영역변경및클립보드로복사, 붙이기가능 화면키보드는입력하는글자를보고후보단어를보여주어긴단어의입력을도와줌 c03_buttonedit.java package exam.andexam; import android.app.*; import android.os.*; import android.view.*; import android.widget.*; public class C03_ButtonEdit extends Activity { public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.c03_buttonedit); } } Button btn = (Button)findViewById(R.id.btn); btn.setonclicklistener(new Button.OnClickListener() { public void onclick(view v) { EditText edit = (EditText)findViewById(R.id.edit); String str = edit.gettext().tostring(); Toast.makeText( C03_ButtonEdit.this, str, Toast.LENGTH_SHORT).show(); } });
2. 리니어레이아웃 v 방향설정 ViewGroup 으로부터파생되는클래스. 차일드뷰를수평, 수직으로일렬배치하는레이아웃으로, 가장단순하면서직관적이며사용빈도높음 orientation 뷰의배치방향을결정하는속성. ( 디폴트는 horizontal) vertical : 차일드를위에서아래로수직으로배열 horizontal : 차일드를왼쪽에서오른쪽으로수평배열 버튼 1 버튼 1 버튼 2 버튼 3 버튼 2 버튼 3 [ vertical ] [ horizontal ]
2. 리니어레이아웃 v 방향설정 c03_horizontal1.xml <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= horizontal android:layout_height= fill_parent > [ Horizontal ] c03_horizontal2.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" >... [ Horizontal2 ] c03_horizontal3.xml <TextView android:layout_width= wrap_content android:text= @string/insa android:textcolor= #ff0000 android:textsize= 20pt android:textstyle= italic /> 에뮬레이터방향가로로변경 [ Horizontal3 ]
2. 리니어레이아웃 v 정렬지정 gravity 내용물의위치를지정하며, 수평, 수직방향에대해각각정렬방식을지정가능 두속성을같이지정할때는 연산자를이용하며, 이때연산자양쪽으로공백이전혀없어야함 각정렬방식은비트필드로정의, center, fill은수평, 수직정렬상태플래그의조합으로정의 상수값설명 center_horizontal 0x01 수평으로중앙에배치한다. left 0x03 컨테이너의왼쪽에배치하며, 크기는바뀌지않는다. right 0x05 컨테이너의오른쪽에배치한다. fill_horizontal 0x07 수평방향으로가득채운다. center_vertical 0x10 수직으로중앙에배치한다. top 0x30 컨테이너의상단에배치하며, 크기는바뀌지않는다. bottom 0x50 컨테이너의하단에배치한다. fill_vertical 0x70 수직방향으로가득채운다. center 0x11 수평으로나수직으로중앙에배치한다. fill 0x77 컨테이너에가득채우도록수직, 수평크기를확장한다.
2. 리니어레이아웃 v 정렬지정 gravity c03_gravity1.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <TextView android:layout_height= fill_parent android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 /> </LinearLayout> c03_gravity2.xml <TextView android:layout_height= fill_parent android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:gravity= center />
2. 리니어레이아웃 v 정렬지정 gravity c03_gravity3.xml <TextView android:layout_height= fill_parent android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:gravity= center_vertical /> c03_gravity4.xml <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:text=" 정렬테스트 " android:textsize="30sp" android:textcolor="#00ff00 android:gravity="center_vertical right"/>
2. 리니어레이아웃 v 정렬지졍 gravity c03_lgravity1.xml <TextView android:layout_width= wrap_content android:layout_height= fill_parent android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:background= #ff0000 android:layout_gravity= center /> c03_lgravity1.xml <TextView android:layout_width= wrap_content android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:background= #ff0000 android:layout_gravity= center /> [ lgravity1 width 만변경 ] [ lgravity1 width, height 모두변경 ]
2. 리니어레이아웃 v 정렬지정 gravity c03_lgravity2.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent android:gravity= center > <TextView android:layout_width= wrap_content android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:background= #ff0000 /> </LinearLayout> c03_lgravity3.xml [ lgravity2 ] [ lgravity3 ] <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent android:gravity= center > <TextView android:layout_width= wrap_content android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:background= #ff0000 /> <Button android:layout_width= wrap_content android:layout_heigth= wrap_content android:text= 버튼이다. /> </LinearLayout>
2. 리니어레이아웃 v 정렬지정 gravity c03_lgravity4.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent android:gravity= center > <TextView android:layout_width= wrap_content android:text= 정렬테스트 android:textsize= 30pt android:textcolor= #00ff00 android:background= #ff0000 android:layout_gravity= center_horizontal android:gravity= right bottom /> </LinearLayout> [ lgravity4 ]
2. 리니어레이아웃 v 베이스정렬 (baselinealigned) 높이가다른차일드뷰를수평으로정렬시하단정렬지정 ( 디폴트 true) c03_base1.xml ~ base2.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= horizontal android:layout_height= fill_parent android:baselinealigned= ture > <TextView android:layout_width= wrap_content android:text= Medium android:textsize= 10pt /> <TextView android:layout_width= wrap_content android:text= Small android:textsize= 5pt android:background= #0000ff /> <TextView android:layout_width= wrap_content android:text= Large android:textsize= 20pt android:typeface= serif /> </LinearLayout> [ base1 ] [ base2 ]
2. 리니어레이아웃 v 차일드영역분할 (layout_weight) 중요도에따라차일드의크기를균등분할 중요도가 0 이면자신의고유한크기만큼, 1 이상이면형제뷰와의비율에따라부모의영역을균등하게배분 c03_weight1.xml ~ weight2.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <Button android:text= 위쪽버튼 android:layout_weight= 1 /> <EditText android:text= 가운데에디트 android:layout_weight= 3 /> <Button android:text= 아래쪽버튼 android:layout_weight= 1 /> </LinearLayout> [ weight1 ] [ weight2 ]
2. 리니어레이아웃 v 차일드영역분할 (layout_weight) c03_weight3.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <Button android:layout_height= 64px android:text= Tool Bar android:layout_weight= 0 /> <EditText android:layout_height= fill_parent android:layout_weight= 1 /> <Button android:layout_height= 64px android:text= Menu Bar android:layout_weight= 0 /> </LinearLayout> [ weight3 ]
2. 리니어레이아웃 v 마진과패딩 (margin, padding) 여백과관련된속성 padding 뷰와내용물간의간격지정 뷰의입장에서볼때안쪽여백을뜻하며뷰자체의속성 4 면모두동일한여백이지정되며, paddingleft, paddingtop, paddingright, paddingbottom 으로 4 면의개별여백지정가능 margin 뷰와부모와의간격을지정하며, 근처에형제뷰가있으면동일한간격으로여백생성 뷰의입장에서볼때바깥여백을뜻하며레이아웃의속성 4 면모두동일한여백이지정되며, layout_marginleft, layout_marginright, layout_margintop, layout_marginbottom 으로 4 면의개별여백지정가능 마진 마진 패딩 패딩 Button
2. 리니어레이아웃 v 마진과패딩 (margin, padding) c03_padding2.xml <LinearLayout android:background= #ff0000 android:layout_margin= 10px > c03_padding3.xml <LinearLayout android:background= #ff0000 android:layout_margin= 10px android:padding= 10px > c03_padding1.xml <?xml version= 1.0 encoding= utf-8 > <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_height= fill_parent > <EditText android:text= Upper Text /> <LinearLayout android:background= #ff0000 > <Button android:text= Button /> </LinearLayout> <EditText android:text= Lower Text /> </LinearLayout> [ padding2 ] [ padding3 ] [ padding1 ]