출처
정재곤, 『Do it! 안드로이드 앱 프로그래밍 - 개정 4판』, 이지스퍼블리싱(주)(2017-06-26), 128-179p
01-1 안드로이드 스튜디오 살펴보기
안드로이드 스튜디오
- 인텔리제이(IntelliJ)라는 개발도구를 확장하여 만든 것
첫째마당을 참고하여 Test 프로젝트 만들기
- 도메인(Domain): 패키지 명을 겹치지 않게 하기 위한 이름
- 계속 Next 버튼 클릭 후 Empty Activity 선택
- 액티비티 이름: MainActivity
- Finish 버튼 누르기
- 프로젝트 닫으려면 File –> Close Project
프로젝트 창의 구성과 기능
File –> Settings –> Editor –> General –> Auto Imports 선택
빠른 메뉴(Quick Access Menu)
Ctrl + Tab –> 개꿀 단축키
Ctrl + Q –> 클래스가 사용하는 API 문서 보기
Ctrl + P –> 함수 파라미터 확인
Generator 사용하기
- MainActivity 클래스에서 onCreate를 재정의하려 함
- onCreate 중괄호 시작점에서 마우스 오른쪽 클릭 후 Generate… 클릭
- Override Methods… 입력
폴더 내 text 검색은 폴더 선택 후 Edit –> Find –> Find in Path…
디자이너 도구 살펴보기
- 딴 건 다 필요없고 res/layout/activity_main.xml에서
- Nexus 4라고 표시된 거 누르면 다른 것으로 해상도 바꿀 수 있음
01-2 뷰와 뷰의 크기 속성 이해하기
뷰의 속성
- 뷰(view): 일반적으로 컨트롤이나 위젯으로 불리는 UI 구성 요소
- 뷰그룹(ViewGroup): 뷰를 여러 개 포함하고 있는 것
- 뷰그룹은 뷰를 상속함 –> 컴포지트 패턴(Composite Pattern)
- TextView 태그를 Button으로 바꾸면 바뀌는 이유도 바로
- TextView를 Button이 상속하였기 때문
위젯과 레이아웃
- 위젯: 사용자의 눈에 보이는 컨트롤의 역할을 하는 화면 구성 요소
- 레이아웃: 뷰들을 배치하는 역할을 하는 것
버튼과 리니어 레이아웃의 계층도
- 레이아웃은 여러 위젯을 담고 위치를 지정
- 레이아웃 안에 레이아웃을 넣으면 레이아웃 안에서 버튼과 같은 위젯으 위치를 잡음
뷰의 크기 속성
- 정리해보면 화면에 추가할 수 있는 모든 것은 뷰
- 뷰는 위젯과 레이아웃으로 구분
- 뷰는 화면의 일정 영역을 차지하므로 크기 속성이 있어야 함
activity_main.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"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
- android:로 시작하는 건 안드로이드의 기본 API에서 정의한 속성이라는 의미
layout_width와 layout_height 속성
- 뷰가 가질 수 있는 내부 속성 중에서 필수 속성
- 각각 가로와 세로를 나타냄
wrap_content: 뷰에 들어 있는 내용물의 크기에 자동으로 맞춤 match_parent: 뷰를 담고 있는 뷰그룹의 여유 공간을 꽉 채움 숫자로 크기 지정: 숫자를 사용해 크기를 지정, 크기는 단위가 꼭 있어야 함
1. 버튼 추가(안녕하세요, 반갑습니다!)
2. layout_width 속성을 match_parent로 변경
3. layout_width를 240dp로 변경
4. ‘Hello World!’ 글자 삭제 후 버튼 layout_width는 wrap_content, layout_height은 match_parent
5. layout_width, layout_height 둘 다 match_parent
- 이런 식으로 나오는 이유는 제약 레이아웃(ConstLayout)이기 때문
- 리니어 레이아웃(LinearLayout)이나 상대 레이아웃(RelativeLayout)이면 결과가 달라짐
01-3 제약 레이아웃 익히기
제약 조건 이해하기
- 제약 레이아웃은 제약 조건(Constraint)를 사용함
- 제약 조건: 뷰가 레이아웃 안의 다른 요소와 어떻게 연결되는지 알려주는 것
- 뷰의 연결점(Anchor Point)과 대상(Target)을 연결
- 버튼 입장에서 부모는 자신을 감싸는 레이아웃 즉, 부모 레이아웃(Parent Layout)
- 최소 2개의 연결점이 2개의 대상과 연결되어야 자신의 위치를 고정됨
대상이 될 수 있는 점
- 같은 레이아웃 안에 들어있는 다른 뷰의 연결점
- 부모 레이아웃의 연결점
- 가이드라인(Guideline)
대상 뷰와 대상의 연결점으로 될 수 있는 것
- 상하좌우(Top, Bottom, Left, Right) left는 Start, Right은 End로도 표시 가능
- 가로축의 가운데(CenterX), 세로축의 가운데(CenterY)
- 베이스라인(Baseline) –> 텍스트를 보여주는 뷰인 경우에만 적용
1. SampleConstraintLayout 프로젝트 만들기
2. activitiy_main.xml 디자인 탭에서 텍스트 지우고 버튼 추가하기
3. 버튼의 왼쪽, 위쪽 연결점을 부모의 대상에 연결하기
4. 오른쪽 Properties창 위에서 왼, 위쪽 값을 80으로 설정하기
- 여기서 설정한 숫자는 마진(Margin)이라 하며 연결점과 대상과의 거리를 나타냄
5. 버튼 하나 더 추가하기
6. 새로 추가한 버튼의 왼쪽 연결점을 기존 버튼과 위쪽 연결점을 위쪽 벽면과 연결
7. Properties창에서 새로 추가한 버튼의 위쪽 마진은 80, 왼쪽 마진은 40으로 설정
화면 가운데에 뷰 배치하기
1. 버튼 하나 더 추가 후 상하좌우 연결점을 전부 부모의 대상에 연결하기
- 이렇게 하면 마진 값은 고려되지 않고 중간에 위치하게 됨
2. Properties 창에서 두 막대기 중 세로 막대기 값을 35로 조정하기
- 바이어스(Bias): 한 쪽으로 얼마나 치우쳐 있는지를 나타내는 값
3. 버튼 꼭짓점을 잡아서 크기 바꾸고 Properties에서 사각형 내부 선이 직선이 됨을 확인하기
- wrap_content에서 특정 dp값으로 바뀜
내부 선의 종류
- 부모 여유 공간 채우기: 구불구불한 선
- 뷰의 내용물 채우기: 중앙을 향하는 화살표
- 고정 크기: 직선
- 여유 공간: 해당 뷰가 차지할 수 있는 공간
가이드라인 사용하기
- 가이드라인(Guideline): 여러 개의 뷰를 일정한 기준 선에 정렬할 때 사용
- 크기가 0이고 화면에 보이지 않음
1. res>layout 폴더에 마우스 오른쪽 버튼 클릭 후 New –> Layout resource file 선택
2. File name: activity_menu.xml, Root element: android.support.constraint.ConstraintLayout
3. 디자이너 도구에서 Guidelines 아이콘 클릭 후 Add Vertical Guideline 선택
4. 가이드라인 선을 끌어당기며 조절해보고 text 탭에서 android.support.constraint.Guideline 태그 찾아 100dp로 바꾸기
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp" />
</android.support.constraint.ConstraintLayout>
- app:layout_constraintGuide_begin=”100dp”
5. 가이드라인 오른쪽에 버튼 세 개 추가하기(왼쪽 연결점은 가이드라인, 위쪽은 위쪽 벽면)
XML 원본에 추가된 속성 확인하기
activity_menu.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">
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="36dp"
android:layout_marginStart="36dp"
android:layout_marginTop="24dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="76dp"
android:layout_marginStart="76dp"
android:layout_marginTop="140dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="132dp"
android:layout_marginStart="132dp"
android:layout_marginTop="248dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
XML 파일에 일반적으로 추가하는 정보
<?xml version="1.0" encoding="utf-8"?>
최상위 레이아웃
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 안드로이드 기본 API에 포함된 위젯이나 레이아웃이 아니면 패키지 이름까지 써야 함
- ConstraintLayout은 기본 API가 아니여서 앞에 패키지 이름을 붙인 것
xmlns:로 시작하는 속성들
- xmlns:android를 예를 들어 보자
- xmlns 뒤의 값은 나머지 속성의 접두어(prefix)로 사용됨
- android:layout_width 속성에서 앞에 있는 android:는 xmlns:android로 지정된 정보를 참조한다는 뜻
xmlns:android
- 안드로이드 기본 SDK에 포함되어 있는 속성을 사용
xmlns:app
- 프로젝트에서 사용하는 외부 라이브러리에 포함되어 있는 속성을 사용
xmlns:tools
- 안드로이드 스튜디오의 디자이너 도구 등에서 화면을 보여줄 때 사용
- 앱이 실행될 때는 적용되지 않고 안드로이드 스튜디오에서만 적용
android:id 속성
- 뷰를 구분하는 구분자 역할을 함
id 속성이 사용되는 두 가지 용도
- XML 레이아웃 파일 안에서 뷰를 구분할 때
- XML 레이아웃 파일에서 정의한 뷰를 자바 소스 파일에서 찾을 때
제약 레이아웃에서 하나의 뷰를 다른 뷰와 연결할 때 사용하는 XML 속성의 이름 규칙
layout _constraint [소스 뷰의 연결점]_[대상 뷰의 연결점]="[대상 뷰의 id]"
제약 레이아웃에서 사용할 수 있는 속성들
layout _constraintTop _toTopOf
layout _constraintTop _toBottomOf
layout _constraintBottom _toTopOf
layout _constraintBottom _toBottomOf
layout _constraintLeft _toTopOf
layout _constraintLeft _toBottomOf
layout _constraintLeft _toLeftOf
layout _constraintLeft _toRightOf
layout _constraintRight _toTopOf
layout _constraintRight _toBottomOf
layout _constraintRight _toLeftOf
layout _constraintRight _toRightOf
가이드라인을 위해 추가된 태그
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp" />
- Guideline 클래스도 외부 라이브러리에 포함된 패키지
- 때문에
andorid.support.constraint
를 붙임 - id 값으로
@+id/guideline
이 설정되어 있음 android:orientation
은 가로, 세로 방향을 결정하는 필수 속성layout_constraintGuide_begin
은 부모 레이아웃과의 거리를 나타냄
부모 레이아웃과 Guideline의 거리를 나타내는 세 가지 속성
1. layout_constraintGuide_begin
세로 방향인 경우 왼쪽부터, 가로 방향인 경우 위쪽부터 거리 지정
2. layout_constraintGuide_end
세로 방향인 경우 오른쪽부터, 가로 방향인 경우 아래쪽부터 거리 지정
3. layout_constraintGuide_percent
layout_constraintGuide_begin 속성 대신 지정하되 %단위로 거리 지정
- 제약 조건을 설정하는 속성은 외부 라이브러리의 속성이여서
app:
접두어가 붙음 - tools:는 디자이너 도구 표시용 속성으로 건들일 필요 없음
거리 단위 여러 가지 있는데 결론은 dp를 써라
dp
- 160dpi 화면을 기준으로 한 픽셀
- px: 픽셀, 화면 픽셀의 수
- 예) 1인치 당 160개의 점이 있는 디스플레이 화면에서 1dp는 1px, 1인치 당 320개의 점이 있는 디스플레이 화면에서는 1dp는 2px와 같음
나머지 부분
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="36dp"
android:layout_marginStart="36dp"
android:layout_marginTop="24dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="76dp"
android:layout_marginStart="76dp"
android:layout_marginTop="140dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="132dp"
android:layout_marginStart="132dp"
android:layout_marginTop="248dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
- 디자이너 도구에서 버튼을 추가하면 버튼의 id가 자동으로 중복되지 않게 붙음
text
속성은 버튼 위에 표시되는 글자를 설정할 때 사용
app:layout_constraintStart_toStartOf
속성
- 이 버튼의 왼쪽의 연결점과 대상 뷰의 왼쪽 연결점을 연결하여 제약 조건을 만들자
layout_marginTop
속성
속성 이름 | 설명 |
---|---|
layout_marginTop | 뷰의 위쪽을 얼마나 띄울지 지정함 |
layout_marginBottom | 뷰의 아래쪽을 얼마나 띄울지 지정함 |
layout_marginLeft | 뷰의 왼쪽을 얼마나 띄울지 지정함 |
layout_marginRight | 뷰의 오른쪽을 얼마나 띄울지 지정함 |
layout_margin | 뷰의 위, 아래, 왼쪽, 오른쪽을 얼마나 띄울지 지정함 |
도전! 01 새 프로젝트 아래쪽에 두 개의 버튼 추가하기
프로젝트 소스: DoitMission-01
1. 제약 레이아웃을 사용해 화면 구성
2. 화면의 아래쪽에 가이드라인을 배치
3. 가이드라인의 위쪽에 버튼을 추가한 후 가이드라인과 연결(적절한 간격 필요)
4. 가이드라인의 위쪽에 버튼을 하나 더 추가한 후 이전에 추가했던 버튼 및 가이드라인과 연결(적절한 간격 필요)
도전! 01 답
activity_main.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"
tools:context=".MainActivity">
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="444dp" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="44dp"
android:layout_marginLeft="64dp"
android:layout_marginStart="64dp"
android:text="버튼 1"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="44dp"
android:layout_marginLeft="64dp"
android:layout_marginStart="64dp"
android:text="버튼 2"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintStart_toEndOf="@+id/button" />
</android.support.constraint.ConstraintLayout>
도전! 02 위, 아래, 중앙의 공간을 차지하는 전형적인 화면 구성하기
프로젝트 소스: DoitMission-02
1. 제약 레이아웃을 사용해 화면을 구성
2. 화면의 위쪽에 버튼을 추가하고 가로 방향으로 꽉 차도록 만들기
3. 화면의 아래쪽에 버튼을 추가하고 가로 방향으로 꽉 차도록 만들기
4. 화면의 가운데에 버튼을 추가하고 위쪽 버튼과 아래쪽 버튼 사이의 중앙 공간을 꽉 채우도록 만들기
도전! 02 답
activity_main.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"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="match+parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</android.support.constraint.ConstraintLayout>
Comments