출처
정재곤, 『Do it! 안드로이드 앱 프로그래밍 - 개정 4판』, 이지스퍼블리싱(주)(2017-06-26), 180-247p
http://wonjerry.tistory.com/5
https://jungwoon.github.io/android/2016/09/22/TextWatcher-Guide/
02-1 대표적인 레이아웃 살펴보기
대표적인 레이아웃 다섯 가지
| 레이아웃 이름 | 설명 |
|---|---|
| 제약 레이아웃 (ConstraintLayout) | 제약 조건(Constraint) 기반 모델 제약 조건을 사용해 화면을 구성하는 방법 안드로이드 스튜디오에서 자동으로 설정하는 디폴트 레이아웃 |
| 리니어 레이아웃(LinearLayout) | 박스(Box) 모델 한 쪽 방향으로 차례대로 뷰를 추가하며 화면을 구성하는 방법 뷰가 차지할 수 있는 사각형 영역을 할당 |
| 상대 레이아웃(ReleativeLayout) | 규칙(Rule) 기반 모델 부모 컨테이너나 다른 뷰와의 상대적 위치로 화면을 구성하는 방법 |
| 프레임 레이아웃(FrameLayout) | 싱글(Single) 모델 가장 상위에 있는 하나의 뷰 또는 뷰그룹만 보여주는 방법 여러 개의 뷰가 들어가면 중첩하여 쌓게 됨 가장 단순하지만 여러 개의 뷰를 중첩한 후 각 뷰를 전환하여 보여주는 방식으로 자주 사용함 |
| 테이블 레이아웃(TableLayout) | 격자(Grid) 모델 격자 모양의 배열을 사용하여 화면을 구성하는 방법 HTML에서 많이 사용하는 정렬 방식과 유사하지만 많이 사용하지는 않음 |
- 스크롤뷰(ScrollView): 스크롤 만드는 방법을 제공, 스크롤뷰 안에 하나의 뷰나 뷰그룹을 넣을 수 있음
- 모든 레이아웃은 layout_width와 layout_height 속성을 가지고 있음
뷰의 영역
- 뷰가 레이아웃에 추가될 때 보이지 않는 뷰의 테두리(Border)가 생김 –> 뷰의 영역(Box)
- 뷰는 테두리를 기준으로 바깥쪽과 안쪽 공간을 띄움
- 마진(Margin): 테두리 바깥쪽 공간
- 패딩(Padding): 테두리 안쪽 공간
마진 값 조정 속성
layout_margin
layout_marginTop
layout_marginBottom
layout_marginLeft
layout_marginRight
패딩 값 조정 속성
padding
paddingTop
paddingBottom
paddingLeft
paddingRight
뷰의 배경색
- background 속성을 설정하여 배경을 그림
- XML에서 #을 붙이고 ARGB(Alpha, Red, Green, Blue)의 순서대로 색상의 값 기록(16진수)
- 예를 들면 #ff000은 빨간색, #00ff00은 녹색이며 앞 두 자리 알파를 추가하여 #ffff0000은 빨간색, #88ff0000은 반투명 빨간색
- 이미지도 배경으로 지정할 수 있으며 이미지 파일은 /res/drawable에 있음 이후 XML에서 android:background=”@drawable/imaegname”
02-2 리니어 레이아웃 사용하기
방항 설정하기
- orientation: 방향 설정
- horizontal: 가로 방향
- vertical: 세로 방향
- 프로젝트 기본 설정이 ConstraintLayout이여서 XML Text 탭에서 XML 원본 코드 바깥에 있는 태그 이름을 LinearLayout으로 바꿔야 함
1. SampleLinearLayout 프로젝트 만들기(Empty Activity)
2. activity_main.xml에서 Hello World 글자 삭제
3. Text 탭을 누르고 android.support.constraint.ConstraintLayout을 LinearLayout으로 변경하기
4. xmlns:app, xmlns:tools, xmlns:context 속성이 있다면 삭제하기
5. andorid: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="match_parent"
android:layout_height="match_parent"
>
</LinearLayout>
6. Design 탭으로 가서 버튼 세 개 추가, layout_width 속성은 match_parent, layout_height 속성은 wrap_content

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
AndroidManifest.xml 파일을 열고 액티비티를 위해 들어 있는 activity 태그의 android:name 속성 값을 바꾸면 지정한 액티비티 화면을 볼 수 있다. 예를 들어, android:name 송성 값을 바꾸면 MainActivity2.java 파일에서 지정한 화면을 볼 수 있다.
<activity android:name=".MainActivity2"></activity>
7. 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="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>

XML 파일을 앱의 시작 화면에 띄워보고 싶으면 MainActivity.java 파일을 열고 setContentView() 메소드 안에 들어가는 파라미터 값을 원하는 XML 파일의 이름을 넣으면 됨. 예를 들면 R.layout.activity_main2
- horizontal로 설정했을 때 버튼이 하나만 보인 이유는 match_parent 속성 때문
- match_parent는 부모 컨테이너의 남아있는 여유 공간을 채움
android:layout_width="match_parent"에서 버튼이 가로 공간을 모두 차지해서 다른 버튼이 추가되지 못한 것
8. 세 버튼의 layout_width 속성을 wrap_content로 바꾸기
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>

- wrap_content는 내용물의 크기에 맞게 뷰의 크기가 결정
- 텍스트뷰, 버튼은 내용물이 텍스트
- 이미지를 보여주는 뷰의 경우 내용물은 이미지
자바 코드에서 화면 구성하기
- 만들어진 XML 파일은 액티비티를 위해 만든 자바 소스 파일과 연결
- MainActivity.java의 setContentView() 메소드가 activity_main.xml을 파라미터로 받아 레이아웃 파일이 액티비티에 설정
- 화면을 바꿀 때 XML을 바꾸는게 쉽긴하지만 화면 레이아웃을 미리 만들 수 없거나 필요할 때마다 레이아웃을 만들 때는 자바 소스 코드에서 화면을 구성해야 함
1. MainActivity.java 파일을 복사하여 LayoutCodeActivity.jav 파일로 만든 후 수정하기

2. 다음과 같이 LayoutCodeActivity.java 파일에 코드 입력
package com.example.kai01.samplelinearlayout;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.LinearLayout;
public class LayoutCodeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// new 연산자로 리니어 레이아웃을 만들고 방향 설정
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
// new 연산자로 레이아웃 안에 추가될 뷰들에 설정할 파라미터 생성
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
// 버튼에 파라미터 설정하고 레이아웃에 추가
Button button01 = new Button(this);
button01.setText("Button 01");
button01.setLayoutParams(params);
mainLayout.addView(button01);
// 새로 만든 레이아웃을 화면에 설정
setContentView(mainLayout);
}
}
- 앱을 실행할 때 처음 보이는 화면을 메인 액티비티라고 함
- 메인 액티비티를 위한 자바 소스 파일의 이름은 MainActivity.java
- 메인 액티비티는 AndroidManifest.xml 파일 안에 자동으로 등록됨
- 메인 액티비티를 LayoutCodeActivity로 변경하면 새로 만든 액티비티가 화면에 나타나게 되는 것
3. app 폴더 안 manifests 폴더 안 AndroidManifest.xml 파일 열어 android:name=".LayoutCodeActivity:>로 수정
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kai01.samplelinearlayout">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LayoutCodeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
4. 실행하기

- MainActivity는
setContentView(R.layout.activity_main);으로 XML로 정의된 리소스를 가리키도록 설정 - LayoutCodeActivity는
setContentView()메소드의 파라미터에 자바 코드에서 만든 뷰그룹 객체 mainLayout을 넣음
// new 연산자로 리니어 레이아웃을 만들고 방향 설정
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
new LinearLayout()의setOrientation()메소드는 리니어 레이아웃 객체 방향setOrientation(LinearLayout.VERTICAL)과 같이 방향 속성을 정의할 수 있음- 뷰 객체를 코드에서 만들 때 뷰의 생성자에는 항상 Context 객체가 전달되어야 함
- AppCompatActivity 클래스는 Context를 상속하므로 이 클래스 안에서는 this를 Context 객체로 사용할 수 있음
컨텍스트(Context)는 어떤 일이 발생한 상황을 의미하는데 객체의 정보를 담고 있는 개게를 의미하며 안드로이드는 UI 구성 요소인 뷰에 대한 정보를 손쉽게 확인하거나 설정할 수 있도록 뷰의 생성자에 Context 객체를 전달하도록 되어 있음
// new 연산자로 레이아웃 안에 추가될 뷰들에 설정할 파라미터 생성
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
- LayoutParams: 뷰를 만들어 뷰그룹에 추가할 때 뷰의 배치를 위한 속성을 설정
- LayoutParams 객체를 새로 만들 경우에는 반드시 뷰의 가로와 세로 속성을 지정해야 함
LayoutParams.MATCH_PARENT와LayoutParams.WRAP_CONTENT외에 가로와 세로의 크기 값을 직접 설정 가능
// 버튼에 파라미터 설정하고 레이아웃에 추가
Button button01 = new Button(this);
button01.setText("Button 01");
button01.setLayoutParams(params);
mainLayout.addView(button01);
// 새로 만든 레이아웃을 화면에 설정
setContentView(mainLayout);
- 소스 코드에서 레이아웃에 뷰를 추가하고 싶으면
addView()메소드 사용 addView()메소드에는 추가할 뷰를 파라미터로 전달하며 LayoutParams 객체도 전달 가능- 이 코드에서는
addView()메소드에 LayoutParams 객체를 전달하지 않고 버튼 객체의setLayoutParams()메소드를 이용해 레이아웃 파라미터를 버튼 객체에 먼저 설정함
// 버튼에 파라미터 설정하고 레이아웃에 추가
Button button01 = new Button(this);
button01.setText("Button 01");
// button01.setLayoutParams(params);
mainLayout.addView(button01, params);
// 새로 만든 레이아웃을 화면에 설정
setContentView(mainLayout);
- 이렇게 쓸 수 있다는 말
뷰 정렬하기
- 정렬(align): 순서대로 놓인다는 의미
- gravity: 어느 쪽에 무게를 둘 것인가 즉 정렬을 의미
레이아웃에서 정렬 기능이 필요한 경우
| 정렬 속성 | 설명 |
|---|---|
| layout_gravity | 부모 컨테이너의 여유 공간에 뷰가 모두 채워지지 않아 여유 공간이 생겼을 때 여유 공간 안에서 뷰를 정렬 |
| gravity | 뷰 안에 표시하는 내용물을 정렬할 때(텍스트뷰의 경우 내용물은 글자가 되고 이미지뷰의 경우 내용물은 이미지가 됨) |
layout_gravity 속성은 layout_으로 시작하고 gravity는 layout_으로 시작하지 않음
1. res/layout 폴더 안에 gravity.xml 만들기

- res/layout 폴더 오른쪽 마우스 –> New –> Layout resource file
- File name: gravity.xml
- Root element: LinearLayout
2. gravity.xml에 다음과 같은 코드 입력하기
<?xml version="1.0" encoding="utf-8"?>
<!-- 리니어 레이아웃을 세로방향으로 지정 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 첫 번째 버튼을 왼쪽으로 정렬 -->
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="left"/>
<!-- 두 번째 버튼을 가운데로 정렬 -->
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="center"/>
<!-- 세 번째 버튼을 오른쪽으로 정렬 -->
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="right"/>
</LinearLayout>
- Design 탭에서 만들 수도 있음

- 여기서 오른쪽 하단 View all attribute를 누르면

- layout_gravity를 설정할 수 있음
3. TextView를 추가하고 gravity 속성과 글자 색을 설정하기 위해 다음과 같이 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<!-- 리니어 레이아웃을 세로방향으로 지정 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 첫 번째 버튼을 왼쪽으로 정렬 -->
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="left"/>
<!-- 두 번째 버튼을 가운데로 정렬 -->
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="center"/>
<!-- 세 번째 버튼을 오른쪽으로 정렬 -->
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="right"/>
<!-- 텍스트뷰 안의 글자를 왼쪽으로 정렬 -->
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#ffff0000"
android:textSize="32dp"
android:text="left"/>
<!-- 텍스트뷰 안의 글자를 오른쪽으로 정렬 -->
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textColor="#ffff0000"
android:textSize="32dp"
android:text="right"/>
<!-- 텍스트뷰 안의 글자를 가로와 세로의 가운데로 정렬 -->
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:textColor="#ffff0000"
android:textSize="32dp"
android:text="center" />
</LinearLayout>
- | 연산자를 이용해 여러 개의 값을 설정할 수 있음 –>
android:gravity="center_horizaontal|center_vertical

버튼이나 텍스트뷰의 크기를 wrap_content로 지정하면 버튼안에 들어 있는 글자에 맞게 뷰의 크기가 결정되므로 내부의 여유 공간이 없다. 따라서 gravity 속성을 지정해도 아무런 변화가 없다.
gravity 속성으로 지정할 수 있는 대표적인 값
| 정렬 속성 값 | 설명 |
|---|---|
| top | 대상 객체를 위쪽 끝에 배치하기 |
| bottom | 대상 객체를 아래쪽 끝에 배치하기 |
| left | 대상 객체를 왼쪽 끝에 배치하기 |
| right | 대상 객체를 오른쪽 끝에 배치하기 |
| center_vertical | 대상 객체를 수직 방향의 중앙에 배치하기 |
| center_horizontal | 대상 객체를 수평 방향의 중앙에 배치하기 |
| fill_vertical | 대상 객체를 수직 방향으로 여유 공간만큼 확대하여 채우기 |
| fill_horizaontal | 대상 객체를 수평 방향으로 여유 공간만큼 확대하여 채우기 |
| center | 대상 객체를 수직 방향과 수평 방향의 중앙에 배치하기 |
| fill | 대상 객체를 수직 방향과 수평 방향으로 여유 공간만큼 확대하여 채우기 |
| clip_vertical | 대상 객체의 상하 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기 top|clip_vertical로 설정한 경우 아래쪽에 남는 부분 잘라내기 bottom|clip_vertical로 설정한 경우 위쪽에 남는 부분 잘라내기 center_vertical|clip_vertical로 설정한 경우 위쪽과 아래쪽에 남는 부분 잘라내기 |
| clip_horizontal | 대상 객체의 좌우 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기 right|clip_horizontal로 설정한 경우 왼쪽에 남는 부분 잘라내기 left|clip_horizoantal로 설정한 경우 오른쪽에 남는 부분 잘라내기 center_horizontal|clip_horizontal로 설정한 경우 왼쪽과 오른쪽에 남는 부분 잘라내기 |
- 텍스드뷰끼리 높이를 맞출 때 layout_gravity와 gravity만으로 힘들 수도 있음
- 이 땐 baselineAligned 속성을 이용하면 됨
4. res/layout 폴더 안에 새로운 baseline.xml 파일 만들고 다음과 같은 코드 입력하기
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 텍스트뷰의 글자 크기를 크게 -->
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="큰 글씨"
android:textColor="#ffff0000"
android:textSize="40dp"
/>
<!-- 텍스트뷰의 글자 크기를 작게 -->
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="중간 글씨"
android:textColor="#ff00ff00"
android:textSize="20dp"/>
<!-- 버튼의 글자 크기를 좀 더 작게 -->
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="작은 글씨"
android:textColor="#ff0000ff"
android:textSize="14dp" />
</LinearLayout>

- 글씨 크기가 각각 다른데도 불구하고 글씨 밑바닥이 일치함
- baselineAligned 속성이 기본적으로 true이기 때문
- 확인하기 위해 baselineAligned 속성을 추가하고 false로 하기
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<!-- 텍스트뷰의 글자 크기를 크게 -->
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="큰 글씨"
android:textColor="#ffff0000"
android:textSize="40dp"
/>
<!-- 텍스트뷰의 글자 크기를 작게 -->
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="중간 글씨"
android:textColor="#ff00ff00"
android:textSize="20dp"/>
<!-- 버튼의 글자 크기를 좀 더 작게 -->
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="작은 글씨"
android:textColor="#ff0000ff"
android:textSize="14dp" />
</LinearLayout>

뷰의 마진과 패딩 설정하기
- 셀(Cell): 뷰의 테두리선 기준으로 바깥, 안쪽 공간을 모두 포함하여 뷰가 가지는 공간
- 웨젯 셀(Widget Cell): 버튼이나 텍스트뷰를 위젯이라 불러 Cell을 일컫는 말
- 마진(Margin): 테두리선을 기준으로 바깥의 공간,
layout_margin으로 얼마나 띄울지 지정 가능 - 패딩(Padding): 테두리선 안쪽의 공간
마진 속성
- layout_marginTop
- layout_marginLeft
- layout_marginRight
- layout_marginBottom
패딩 속성
- paddingTop
- paddingLeft
- paddingRight
- paddingBottom
1. res/layout 폴더에 padding.xml 파일 만들고 다음과 같은 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 텍스트뷰 위젯 내부의 여백을 20dp로 설정 -->
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:background="#ffffff00"
android:padding="20dp"/>
<!-- 텍스트뷰 위젯과 부모 여유 공간 사이의 여백을 10dp로 설정 -->
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:background="#ff00ffff"
android:layout_margin="10dp"/>
<!-- 텍스트뷰 내부의 여백을 20dp로 설정 -->
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:background="#ffff00ff"
android:padding="20dp"/>
</LinearLayout>

- padding이나 layout_margin 속성을 너무 크게 잡으면 이상한 모양이 나오니 잘 설정하기 바람
여유 공간 분할하기
layout_weight: 부모 컨테이너에 남아 있는 여유 공간을 분할하여 기존에 추가 했던 뷰들에게 할당 가능layout_width나layout_height로 지정하는 뷰의 크기는 wrap_content나 숫자 값을 지정되어야 함
layout_weight속성으로 각 뷰에 할당하는 크기는 추가적인 값이다. 즉,layout_width나layout_height로 지정한 크기에 추가되는 값이다. 예를 들어, 가로 방향으로 두 개의 버튼을 추가했을 때 두 개의 버튼을 제외한 나머지 여유 공간이 있다면 그 여유 공간을 분할한 후 이 두 개의 버튼에 할당하게 된다.
1. res/layout 폴더 안에 weight.xml 파일 만들고 다음과 같은 코드 입력하기
<?xml version="1.0" encoding="utf-8"?>
<!-- 리니어 레이아웃을 수직 방향으로 설정 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 리니어 레이아웃을 수평 방향으로 설정 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>

- 두 개의 텍스트뷰는 layout_width 속성으로 지정된 가로 크기가 동일하므로 여기에 동일한 크기의 여유 공간을 더해주어도 두 개의 텍스트뷰가 동일한 가로 크기를 갖게 됨
2. 두 개의 텍스트뷰를 추가한 후 layout_weight 속성 값을 1과 2로 지정
<?xml version="1.0" encoding="utf-8"?>
<!-- 리니어 레이아웃을 수직 방향으로 설정 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 리니어 레이아웃을 수평 방향으로 설정 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_weight를 2로 설정 -->
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="2"/>
</LinearLayout>
</LinearLayout>

- 오른쪽에 남아있던 여유 공간은 1/3, 2/3씩 분할되어 두 개의 뷰에 할당된 것
- 하지만 부모 컨테이너의 가로 공간을 두 개의 텍스트 뷰가 1:2로 나누어 가진게 아님
- 두 개의 뷰가 남아있던 여유 공간을 분할하여 가진 것
- 부모 컨테이너의 가로 공간을 1:2로 나눠 가지려면 layout_width 속성 값을 0dp로 설정해야 함
3. 방향 속성(orientation 속성) 값이 horizontal인 리니어 레이아웃 추가하고 다음 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<!-- 리니어 레이아웃을 수직 방향으로 설정 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 리니어 레이아웃을 수평 방향으로 설정 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_weight를 2로 설정 -->
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="2"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- layout_width를 0dp로 한 후 layout_weight를 1로 설정 -->
<TextView
android:id="@+id/textView5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="1"/>
<!-- layout_width를 0dp로 한 후 layout_weight를 2로 설정 -->
<TextView
android:id="@+id/textView6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#ff00ffff"
android:text="텍스트"
android:textColor="#ffff0000"
android:textSize="24dp"
android:layout_weight="2"/>
</LinearLayout>
</LinearLayout>

리니어 레이아웃은 한 방향으로만 뷰를 넣어 원하는 화면을 만들기 어렵다고 생각할 수 있지만 레이아웃 안에는 레이아웃을 추가할 수 있기 때문에 어떤 모양이든 대부분 만들 수 있다. 예를 들머 왼쪽에 이미지가 있고 오른쪽에 글자가 위, 아래로 배치된 모양을 만들고 싶다면 다음과 같이 레이아웃을 만들 수 있다. LinearLayout 태그의 orientation 속성을 제외한 나머지 속성들은 제외하고 표시한 모양이다.
<LinearLayout
android:orientation="horizontal">
<ImageView />
<LinearLayout
android:orientation="vertical ">
<TextView />
<TextView />
</LinearLayout>
</LinearLayout>
- 리니어 레이아웃의 정렬, 마진, 패딩 속성은 다른 레이아웃에서도 적용 가능
02-3 상대 레이아웃 사용하기
상대 레이아웃
- 부모 컨테이너나 다른 뷰와의 상대적인 위치를 이용해 뷰의 위치를 결정
- 버튼 밑에 버튼을 추가하고 싶으면 이미 추가되어 있는 버튼의 id가 필요
1. 모두 기본값 SampleRelativeLayout을 만들기
2. activity_main.xml에서 ‘Hello World! 글자 삭제
3. text 탭에서 다음과 같이 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_above="@+id/button2"
android:text="Button"
android:background="#ff0088ff"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Button" />
</RelativeLayout>
- 첫 번째 버튼을 보면
layout_alignParentLeft, layout_alignParentStart, layout_alignParentTop속성이 모두 “true”- 이 속성은 각각 부모 레이아웃의 왼쪽, 시작 부분, 위쪽에 붙이라는 의미
-
layout_above속성을 추가하면서 두 번째 버튼의 id를 지정하여 첫 번째 버튼을 두 번째 버튼의 바로 윗부분까지만 공간을 차지하게 함 - 두 번째 버튼을 보면
layout_alignParentBottom: 버튼을 아래쪽으로 정렬하기 위한 속성 –> 부모 레이아웃의 아래쪽으로 붙이라는 속성

5. 위쪽 공간에 버튼 배치를 위해 다음과 같은 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_above="@+id/button2"
android:text="Button"
android:background="#ff0088ff"
android:layout_below="@+id/button3"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="Button"/>
</RelativeLayout>

상대 레이아웃에서 부모 컨테이너와의 상대 위치를 이용해 뷰를 배치할 수 있는 속성
| 속성 | 설명 |
|---|---|
| layout_alignParentTop | 부모 컨테이너의 위쪽과 뷰의 위쪽을 맞춤 |
| layout_alignParentBottom | 부모 컨테이너의 아래쪽과 뷰의 아래쪽을 맞춤 |
| layout_alignParentLeft | 부모 컨테이너의 왼쪽 끝과 뷰의 왼쪽 끝을 맞춤 |
| layout_alignParentRight | 부모 컨테이너의 오른쪽 끝과 뷰의 오른쪽 끝을 맞춤 |
| layout_centerHorizontal | 부모 컨테이너의 수평 방향 중앙에 배치함 |
| layout_centerVertical | 부모 컨테이너의 수직 방향 중앙에 배치함 |
| layout_centerlnParent | 부모 컨테이너의 수직 방향 중앙에 배치함 |
부모 컨테이너가 아닌 다른 뷰와의 상대적 위치를 이용해 뷰를 배치하는 속성
| 속성 | 설명 |
|---|---|
| layout_above | 지정한 뷰의 위쪽에 배치함 |
| layout_below | 지정한 뷰의 아래쪽에 배치함 |
| layout_toLeftOf | 지정한 뷰의 왼쪽에 배치함 |
| layout_toRightOf | 지정한 뷰의 오른쪽에 배치함 |
| layout_alignTop | 지정한 뷰의 위쪽과 맞춤 |
| layout_alignBottom | 지정한 뷰의 아래쪽과 맞춤 |
| layout_alignLeft | 지정한 뷰의 왼쪽과 맞춤 |
| layout_alignRight | 지정한 뷰의 오른쪽과 맞춤 |
| layout_alignBaseline | 지정한 뷰와 내용물의 아래쪽 기준선(baseline)을 맞춤 |
- 어짜피 안드로이드 스튜디오가 속성을 미리 보여주니 외울 필요는 없음
- 상대 레이아웃 또한 상대 레이아웃만으로 화면을 만들지 않고 다른 레이아웃과 함께 사용
02-4 테이블 레이아웃
테이블 레이아웃
- 표나 엑실 시트와 같은 형태로 화면을 구성하는 레이아웃
- TableRow: 한 행을 의미하며 여러 개의 뷰가 들어가는데 이 뷰들은 각각 하나의 열을 의미
1. 모두 기본 설정 SampleTableLayout 프로젝트 만들기
2. activity_main.xml의 최상위 레이아웃을 TableLayout으로 변경
3. TextView 태그 모두 삭제
4. Design 탭에서 TableRow 2개 추가

- layout_width, layout_height 속성은 모두 match_parent로 자동 설정 됨
- match_parent로 설정되어 있어도 아래쪽 여유 공간을 다 차지하지 않음
- TableRow의 높이 값은 내부적으로 항상 wrap_content로 설정되어 있기 때문
- 반대로 TableRow의 폭은 내부적으로 항상 match_parent로 설정되어 있음
5. 각각의 TableRow 안에 세 개의 버튼 추가하기

- 버튼을 디자인 화면에 추가하기가 힘드므로 위와 같이 Component Tree로 드래그해야 추가 가능

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 테이블의 첫 번째 행 -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</TableRow>
<!-- 테이블의 두 번째 행 -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</TableRow>
</TableLayout>
6. 테이블 행의 가로 공간을 꽉 채우기 위해 TableLayout 태그에 stretchColumns 속성 추가
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="0,1,2">
<!-- 테이블의 첫 번째 행 -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</TableRow>
<!-- 테이블의 두 번째 행 -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</TableRow>
</TableLayout>
- 칼럼은 0부터 시작
- stretchColumns에 0을 넣으면 첫 번째 버튼이 여유 공간 차지
- stretchColumns에 0, 1을 넣으면 첫, 두 번째 버튼이 여유 공간 차지
- stretchColumns에 0, 1, 2를 넣으면 첫, 두, 세 번째 버튼이 여유 공간 차지

- shirinkColumns: 부모 컨테이너의 폭에 맞추도록 각 열의 폭을 강제 축소
- stretchColumns: 부모 컨테이너의 폭에 맞추도록 각 열의 폭을 강제 확대
- layout_column: TableRow 태그에 추가되는 뷰는 자동으로 0, 1, 2와 같은 칼럼 인덱스를 받지만 이것을 사용해서 칼럼 인덱스를 지정할 수 있음
- layout_span: 뷰가 여러 칼럼에 걸쳐 있도록 만들기 위한 속성, 몇 개의 칼럼을 차지하게 할 것인지 숫자로 지정
7. activity_input.xml 생성하고 다음 코드 입력하기
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff3366cc"
android:stretchColumns="0,1,2">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="이름 : "/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="3" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:text="아니오" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="예" />
</TableRow>
</TableLayout>
- 테이블 레이아웃 첫 번째 줄에는 하나의 텍스트뷰와 하나의 입력상자
layout_span속성을 추가하고 그 값을 3으로 지정하여 입력상자가 세 개의 칼럼 영역을 차지- 다음 TableRow에서는 버튼이 두 개 추가 되었는데 첫 번째 버튼이
layout_column으로 2가 지정됨 - 따라서 0과 1 인덱스의 위치에는 아무 것도 없고 2와 3 인덱스 위치에 두 개의 버튼이 위치하게 됨

- 그리드뷰가 상위호환이여서 테이블 레이아웃은 잘 사용 안 함 ㅎ
02-5 스크롤뷰 사용하기
스크롤뷰
- 추가된 뷰의 영역이 한눈에 다 보이지 않을 때 사용
- 스크롤뷰 안에 뷰를 넣는 방식으로만 스크롤이 가능
- ScrollView 태그를 사용하여 하나의 뷰를 넣음
1. 기본 설정 SampleScrollView 프로젝트 생성
2. res/drawable 폴더에 두 개의 이미지 넣기(이미지 파일에는 대문자 사용 불가)
3. activity_main.xml에 다음 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- 이미지 변경을 위한 버튼 -->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="이미지 바꾸어 보여주기"
android:onClick="onButton1Clicked"/>
<!-- 수평 스크롤을 위한 스크롤 뷰 -->
<HorizontalScrollView
android:id="@+id/horScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- 이미지를 보여주는 이미지뷰 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</ScrollView>
</HorizontalScrollView>
</LinearLayout>
- 스크롤뷰는 기본적으로 수직 방향의 스크롤 지원
- 수평 방향의 스크롤을 사용하려면 HorizontalScrollView를 이용
- ImageView 태그는 이미지를 화면에 보여줄 때 사용
- 텍스트뷰나 버튼을 자바 코드에서 추가 가능하듯이 이미지도
new ImageView(this)로 추가 가능 - 이미지뷰에 설정된 이미지가 큰 경우 수평과 수직 스크롤을 모두 나타나도록 HorizontalScrollView 안에 ScrollView를 추가한 후 그 안에 이미지뷰 추가하기
- 이미지가 화면을 벗어날 경우 스크롤이 나타남
onClick과onButton1Clicked는 버튼을 클릭하면 XML 레이아웃 파일과 매칭되는 자바 소스 파일에서onButton1Clicked라는 이름의 메소드를 찾아 실행
4. MainActivity.java 파일을 열고 다음 코드 추가
package com.example.kai01.samplescrollview;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ScrollView;
public class MainActivity extends AppCompatActivity {
ScrollView scrollView;
ImageView imageView;
BitmapDrawable bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 레이아웃에 정의된 뷰 객체 참조
scrollView = (ScrollView) findViewById(R.id.scrollView);
imageView = (ImageView) findViewById(R.id.imageView);
// 수평 스크롤바 사용 기능 설정
scrollView.setHorizontalScrollBarEnabled(true);
// 리소스의 이미지 참조
Resources res = getResources();
bitmap = (BitmapDrawable) res.getDrawable(R.drawable.image01);
int bitmapWidth = bitmap.getIntrinsicWidth();
int bitmapHeight = bitmap.getIntrinsicHeight();
// 이미지 리소스와 이미지 크기 설정
imageView.setImageDrawable(bitmap);
imageView.getLayoutParams().width = bitmapWidth;
imageView.getLayoutParams().height = bitmapHeight;
}
public void onButton1Clicked(View v) {
changeImage();
}
// 다른 이미지 리소스 변경
private void changeImage() {
Resources res = getResources();
bitmap = (BitmapDrawable) res.getDrawable(R.drawable.image02);
int bitmapWidth = bitmap.getIntrinsicWidth();
int bitmapHeight = bitmap.getIntrinsicHeight();
imageView.setImageDrawable(bitmap);
imageView.getLayoutParams().width = bitmapWidth;
imageView.getLayoutParams().height = bitmapHeight;
}
}
findViewById()메소드로R.id.scrollView와R.id.imageView라는 id 값을 파라미터로 전달- XML 레이아웃 파일에서 id 지정: @+id/아이디
- 자바 소스 코드에서 참조: R.id.아이디
- 프로젝트에 추가된 이미지는
getDrawable()메소드를 이용해 코드에서BitmapDrawable객체로 만들어짐 getDrawable()메소드는Resources객체에 정의되어 있으며 액티비티에 정의된getResources()메소드를 이용하면Resources객체 참조 가능BitmapDrawable객체의getIntrinsicWidth()와getIntrinsicHeight()메소드는 원본 이미지의 가로와 세로 크기를 알아냄- 알아낸 가로 세로 크기 값은 이미지뷰에 설정된
LayoutParams객체의 width, height 속성으로 설정 가능
setImageResource()메소드는 XML 레이아웃 파일에서 ImageView 태그의 속성으로 src 속성을 추가하면서 그 값으로R.drawable.image01처럼 이미지 파일을 지정하는 것과 같다.setImageDrawable()메소드는 이미지 파일을Drawable객체로 만든 후 이미지뷰에 설정할 때 사용한다. 그런데 설명한 두 메소드 중 하나를 사용하면 이미지뷰가 이미지의 크기를 화면 크기에 맞게 자동으로 줄이기 땜누에 원본 이미지의 크기 그대로 이미지뷰에 보이게 이미지의 가로와 세로 크기를 직접 설정해야 스크롤뷰 안에서 스크롤을 사용해 원본 이미지를 볼 수 있다.
5. 메인 액티비티 실행하기
실행 화면, 스크롤을 움직일 수 있음

이미지 바꾸어 보여주기를 눌렀을 때 화면, 역시 스크롤을 움직일 수 있음

02-6 프레임 레이아웃과 뷰의 전환
프레임 레이아웃
- 가장 기본적이고 단순한 레이아웃
- 프레임 레이아웃에 뷰를 넣으면 그 중에 하나의 뷰만을 화면에 표시
- 중첩(Overlay) 기능으로 가시성(Visibility) 속성을 구현할 수 있어 자주 사용
- 디자이너 도구에서 프레임 레이아웃에 여러 개의 뷰를 추가하거나 자바 소스코드에서
addView()나removeView()와 같은 메소드를 사용해 뷰를 추가하거나 삭제할 수 있음 - 가시성(Visibility) 속성을 사용해서 특정 뷰를 보이거나 보이지 않게 홤녀에 보이는 뷰를 전환하는 효과를 만들 수 있음
- 하나의 화면으로 표시되는 액티비티 안에서도 여러 개의 뷰가 전환되도록 만들 수 있음
1. 기본 설정 SampleFrameLayout 프로젝트 생성
2. activity_main.xml에 다음 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- 이미지 전환 버튼 -->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="이미지 바꾸기"
android:onClick="onButton1Clicked" />
<!-- 프레임 레이아웃으로 나머지 화면 채우기 -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- 첫 번째 이미지뷰를 안 보이도록 설정 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/dream01"
android:visibility="invisible"
/>
<!-- 두 번째 이미지뷰를 보이도록 설정 -->
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/dream02"
android:visibility="visible"
/>
</FrameLayout>
</LinearLayout>
- 화면에 있는 버튼을 누를 때마다 두 개의 이미지가 전환되는 기능을 넣은 것
- 화면 레이아웃에는 위쪽에 버튼을 하나 두고 그 아래에 이미지가 보이게 함
- 이미지는 버튼을 누를 때마다 전환되어야 하므로 프레임 레이아웃 안에는 두 개의 이미지뷰를 중첩
- dream02가
android:visibility="visible"이므로 먼저 보임 - 물론 이 값을 설정하지 않아도 dream02가 나중에 쌓여서 먼저 보임
3. MainActivity.java에 다음 코드 입력
package com.example.kai01.sampleframelayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
ImageView imageView2;
int imageIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
imageView2 = (ImageView) findViewById(R.id.imageView2);
}
public void onButton1Clicked(View v) {
changeImage();
}
private void changeImage() {
// 첫 번째 이미지뷰가 보이게 설정
if(imageIndex == 0) {
imageView.setVisibility(View.VISIBLE);
imageView2.setVisibility(View.INVISIBLE);
imageIndex = 1;
// 두 번째 이미지뷰가 보이게 설정
} else if (imageIndex == 1) {
imageView.setVisibility(View.INVISIBLE);
imageView2.setVisibility(View.VISIBLE);
imageIndex = 0;
}
}
}
findViewById()메소드로 이미지뷰를 찾아 변숭 ㅔ할당- 버튼을 눌렀을 때 호출되는
changeImage()메소드 안에서 두 개의 이미지뷰가 갖는 가시성 속성을 변경 View.VISIBLE또는View.INVISIBLE상수로 설정하면 XML에서 “visible”, “invisible”로 설정한 것과 같음imageIndex변수는 어떤 이미지뷰가 프레임 레이아웃에 보이고 있는지 알 수 있도록 선언한 것(첫 이미지는 0, 두 번째 이미지는 1)
4. 메인 액티비티 실행하기
처음 보여주는 이미지

이미지 바꾸기를 눌렀을 때 보여주는 이미지

02-7 기본 위젯들
- 기본 위젯들이 갖고 있는 주요 속성을 정리하겠음
- 우선 기본 설정 SampleWidget 프로젝트를 만들자
텍스트뷰
- “Hello World!!!”와 같은 텍스트를 화면에 보여주는 역할
text
- 보이는 문자열 설정
- 텍스트뷰가 차지하는 영역을 알 수 있게 문자열은 반드시 지정해야 함
- XML 레이아웃에 들어 있는 텍스트뷰에 text 속성을 추가할 때 직접 문자열 값을 입력할 수 있음
- /res/value 폴더 안에 들어 있는 strings.xml 파일 안에 들어 있는 문자열을 지정할 수도 있음
- strings.xml 파일 안 string 태그 문자열은 다른 곳에서 name 속성 값으로 참조하여 사용 가능
1. strings.xml에 다음 코드를 입력
<resources>
<string name="app_name">SampleWidget</string>
<string name="person_name">김진수</string>
</resources>
2. activity_main.xml에 다음 코드를 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:text="@string/person_name"
/>
</LinearLayout>

안드로이드는 다국어를 지원하고 이를 이용하려면 res 폴더안 values-로케일(해당국가 언어) 폴더를 만들고 그 안에 strings.xml을 정의해야 한다. 예를 들어 한국어 로케일을 사용하는 것으로 하려면 res/values-ko 폴더를 만들고 그 안에 들어 있는 strings.xml 파일 안에 한국어로 된 글자를 입력하고 영문 로케일을 사용하는 것으로 하려면 res/values-en 폴더를 만들고 그 안에 들어 있는 strings.xml 파일 안에는 영어로 된 글자를 입력한다. 이렇게 정의하면 단말의 설정(Setting)에서 언어(Language)를 영어에서 한국어로 바꿀 경우에 res/values-ko/strings.xml에 들어 있는 문자열이 화면에 표시된다.
textColor
- ARGB 두 글자 씩
- Alpha에서 FF는 투명하지 않게, 88은 반투명하게, 00은 투명하게
- 예를 들어 빨간색은 #FFFFFFFF
textSize
- 텍스트뷰에서 표시하는 문자열의 크기를 설정
- 단위는 dp, sp, px를 사용하는데 정확한 폰트 크기를 사용할 땐 sp를 사용
textStyle
- “normal”, “bold”, “italic” 등의 값을 지정할 수 있으며 |을 이용하여 여러 개의 속성 값을 지정할 수 있음
typeFace
- 폰트 설정
- “normal”, “sans”, “serif”, “monospace”가 있음
maxLines
- 텍스트뷰에서 표시하는 문자열의 최디 줄 수를 설정
- 한 줄로만 표시하고 싶은 경우 값을 1로 설정 –> 한 줄의 영역을 넘어가는 부분은 표시되지 않음
1. 화면 레이아웃에 텍스트뷰 추가하기
2. 다음과 같은 속성을 추가하기
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:text="@string/person_name"
/>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#88aabbff"
android:padding="40dp"
android:text="여기에 사용자 이름을 입력하세요."
android:textSize="22dp"
android:textStyle="bold"
android:textColor="#ffff8888"
android:maxLines="1"
android:gravity="center" />
</LinearLayout>

버튼
- 체크 박스나 라디오 버튼도 제공
- 버튼 위젯에 발생하는 이벤트 처리는 OnClickListener가 간단
- 체크 박스와 리다오 버튼은 클릭 이벤트와 상태 값을 저장하고 선택/해제 상태를 표시해야 함
- 이를 위한 CompoundButton 클래스는 다음과 같은 메소드를 가지고 있음
public boolean isChecked()
public void setChecked(boolean checked)
public void toggle()
- 상태가 바뀔 경우 다음 메소드가 호출
void on CheckedChanged(CompoundButton buttonView, boolean isChecked)
라디오 버튼
- 라디오 버튼은 하나를 선택하면 다른 것이 해제되어야 함
- 이를 위해 RadioGroup을 이용해 하나의 그룹으로 묶어주게 됨
- RadioGroup 태그 안에 포함된 RadioButton은 모두 같은 그룹 안에 있는 라디오 버튼으로 인식
check()메소드에 라디오 버튼 ID 값이 아닌 -1을 파라미터로 전달하면 라디오 버튼 선택 상태를 모두 해제 가능- 라디오 버튼 선택 상태가 변경될 때 이벤트를 받아 처리하고자 한다면
OnCheckedChangeListner인터페이스 구현 후setOnCheckedChangeListener()메소드로 설정
1. res/layout 폴더 안에 button.xml 파일을 만들고 다음 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 기본 버튼 -->
<Button
android:id="@+id/btnExit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="선택"
android:textSize="24dp"
android:textStyle="bold"
android:gravity="center"
/>
<!-- 라디오 버튼 두 개를 묶어놓은 라디오 그룹 -->
<RadioGroup
android:id="@+id/radioGroup01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
>
<!-- 첫 번째 라디오 버튼 -->
<RadioButton
android:id="@+id/radio01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="남성"
android:textColor="#ff55aaff"
android:textStyle="bold"
android:textSize="24dp"
/>
<!-- 두 번째 라디오 버튼 -->
<RadioButton
android:id="@+id/radio02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="여성"
android:textColor="#ff55aaff"
android:textStyle="bold"
android:textSize="24dp"
/>
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:paddingTop="20dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="하루종일"
android:textSize="24dp"
android:paddingRight="10dp"
android:textColor="#ff55aaff"
/>
<!-- 체크 박스 -->
<CheckBox
android:id="@+id/allDay"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

2. MainActivity.java 파일에 다음과 같은 코드 입력 후 실행
package com.example.kai01.samplewidget;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.button);
}
}

- 버튼에 아이콘을 넣고 싶으면 속성 추가로 가능
- 텍스트가 아예 없는 버튼을 사용하고 싶으면 ImageButton 태그 사용
입력상자
- 에디트텍스트(EditText)는 사용자의 입력을 받고자 할 때 일반적으로 사용
1. res/layout 폴더 안에 edittext.xml 파일 만들고 다음 코드 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/usernameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24dp"
android:inputText="textCapWords"
android:hint="이름을 입력하세요."/>
</LinearLayout>
- hint 속성은 입력하기 전 안내글 표시
- inputType 속성은 입력되는 글자 유형 정의
- inputType에 숫자만 넣고 싶으면 “number”

이미지뷰
- 이미지를 화면에 표시하려고 제공되는 가장 간단한 위젯 중 하나
- 이미지를 로딩하여 설정하려면 /res/drawable 폴더 밑에 이미지 파일을 복사하여 넣은 후
- 이미지뷰의 src 속성 값으로 이미지 파일을 지정
- 포멧은
@drawable/이미지명사용 - 이미지뷰의 대표적인 속성은 다음과 같음
src
- 원본 이미지를 설정
maxWidth, maxHeight
- 이미지가 보일 최대 크기 설정
tint
- 이미지뷰에 보이는 이미지 위에 색상을 적용하고 싶을 때 설정
scaleType
- 이미지가 원본 이미지의 크기와 다르게 화면에 보이는 경우 확대/축소를 어떤 방식으로 적용할지 설정
- fitXY, centerCrop, centerInside 등 여러 가지 값이 미리 정의되어 있음
drawable 폴더는 이름을 다르게 적용하면 화면의 해상도에 따라 서로 다른 이미지를 로딩할 수 있다. 예를 들어 /res/drawable-xhdpi, /res/drawable-hdpi, /res/drawable-mdpi, /res/drawable/idpi 등이 있다.
1. res/layout 폴더 안에 image.xml 파일을 만들고 다음 코드를 입력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 이미지 버튼을 사용해 이미지 추가 -->
<ImageButton
android:id="@+id/imageButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="40dp"
android:layout_marginLeft="40dp"
android:background="@drawable/ok_btn"
android:contentDescription="ok button"
>
</ImageButton>
<!-- 이미지뷰를 사용해 이미지 추가 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="160dp"
android:layout_marginLeft="160dp"
android:background="@drawable/person"
android:contentDescription="person button"
>
</ImageView>
</LinearLayout>

- 이미지를 화면에 보여주는 가장 간단한 방법은 이미지뷰(ImageView)
- 버튼처럼 만들고 싶은 경우에 이미지 버튼(ImageButton)
텍스트뷰와 입력상자의 다른 기능들
- 안드로이드의 뷰가 가지는 속성은 오지게 많음
커서
- 에디트텍스트는 문자나 숫자를 입력하는 입력상자의 역할을 하므로 커서가 깜박
- 이 커서는 포커스를 받으면 입력되어 있는 문자열의 제일 끝으로 이동
- selectAllOnFocus 속성을 설정하면 포커스를 받을 때 문자열 전체가 선택
- 문자열 전체가 선택되면 새로운 문자를 입력했을 때 입력되어 있던 문자열을 한꺼번에 대체 가능
- 문자열 전체가 선택되어 있는 상태에서 문자열을 대체하지 않고 추가하고 싶다면 왼쪽이나 오른쪽 이동 키를 한 번 누르고 입력
- 커서를 보이게 하기 싫다면 cursorVisible 속성을 “false”로 설정
- 에디트텍스트를 길게 누르면 사용자가 문자열을 선택하거나 복사, 잘라내기 등의 작업을 할 수 있음
- 이러한 기능을 코드에서 동작하게 하려면 다음과 같은 메소드를 사용해야 함
public int getSelectionStr()
public int getSelectionEnd()
public void setSelection(int start, int stop)
public void setSelection(int index)
public void selectAll()
public void extendSelection(int index)
getSelectionStart()메소드는 선택된 영역이 있을 때 그 시작 위치를 알려줌getSelectionEnd()메소드는 끝 위치를 알려주는데 두 개의 메소드 모두 선택 영역이 없으면 커서가 있는 현재 위치를 알려줌setSelect()메소드는 선택 영역을 지정하는데 사용함extendSelection()메소드는 선택 영역을 확장하는데 사용selectAll()메소드를 호출하면 전체 문자열이 선택됨
자동 링크
- 링크가 들어있으면 링크 색상으로 표시하고 링크를 누르면 웹 페이지에 접속하거나 메일 편집기를 띄워주는 기능
- autoLink 속성을 사용하여 안드로이드에서 만들 수 있음
줄 간격 조정
- lineSpacingMultiplier는 줄 간격을 배수로 설정할 때 사용
- lineSpaceExtra는 여유 값으로 설정할 때 사용
- 배수로 설정할 때 값이 1.0보다 작으면 기본으로 설정되어 있는 값보다 더 좁게 보임
- 실제론 lineSpacingExtra 속성만으로 충분
대소문자 표시
- capitalize 속성은 문자를 대문자나 소문자로 바꾸어 표시하는 기능을 제공
- “characters”, “words”, “sentences”등이 있음
- 설정하게 되면 글자, 단어, 문장 단위로 맨 앞 글자를 대문자로 표시
줄임 표시
- 텍스트뷰에서 줄이 넘어가면 문자열의 뒷부분은 잘리고 “…“으로 표시됨
- 이 때 ellipsize 속성을 이용하면 문자열의 어디를 잘라서 표시할 것인지 설정 가능
- 디폴트 값은 “none”이고 뒷 부분을 자르고 “start”, “middle”, “end” 값들은 각각 앞부분, 중간부분, 뒷부분을 잘라서 보여줌
- 텍스트뷰를 한 줄로 표시할 때는 maxLines 속성을 사용
힌트 표시
- 아무 내용도 입력되지 않았을 때 hint 속성에 입력한 글자가 표시됨
- 힌트로 표시한 글자의 색상을 바꾸고 싶으면 textColorHint 속성을 이용
편집 기능
- 에디트텍스트에 입력되어 있는 문자열을 편집하지 못하게 하고 싶으면 editable 속성 값을 “false”로 설정
- 디폴트 값은 “true”
문자열 변경 처리
getText()메소드: 에디트텍스트에 입력된 문자를 확인하거나 입력된 문자가 필요한 포맷과 맞는지 확인getText()메소드의 리턴 객체는Editable인데 이 객체의toString()메소드를 이용하면 일반 String 타입의 문자열 확인 가능- 문자열이 사용자의 입력에 의해 바뀔 때마다 확인하는 기능을 넣고 싶다면
TextChangedListner를 사용
public void addTextChangedListener(TextWatcher watcher)
addTextChangedListener()메소드를 이용하면TextWatcher객체를 설정할 수 있음- 이 객체는 테스트가 변경될 때마다 발생하는 이벤트를 처리할 수 있음
TextWatcher인터페이스에는 다음과 같은 메소드가 정의되어 있음
public void beforeTextChanged(CharSequence s, int start, int count, int after)
public void afterTextChanged(Editable s)
public void onTextChanged(CharSequence s, int start, int before, int count)
- 문자열이 편집되기 전과 후 그리고 편집된 정보를 확인가능
- 따라서 필요한 기능을 추가해야 함
- 입력된 문자열의 길이 값을 확인할 때는
setFilters()메소드를 이용해InputFilter객체를 파라미터로 전달 -
InputFilter객체의LengthFilter()메소드를 호출하면 입력된 문자열의 길이 값을 설정할 수 있음 TextWatcher인터페이스의 활용 예는 SMS로 전송하는 경우- SMS는 80바이트까지만 전송할 수 있으므로 사용자가 몇 글자를 입력했는지 바로바로 표시해 주고 싶을 때 이 클래스를 사용
도전! 03 두 개의 이미지뷰에 이미지 번갈아 보여주기
프로젝트 소스: DoitMission-03
1. 화면을 위와 아래 두 영역으로 나누고 그 영역에 각각 이미지뷰를 배치
2. 각각의 이미지뷰는 스크롤이 생길 수 있도록 함
3. 상단의 이미지뷰에 하나의 이미지를 보이도록 함
4. 두 개의 이미지뷰 사이에 버튼을 하나 만들고 그 버튼을 누르면 상단의 이미지가 하단으로 옮겨져 보이고 다시 누르면 상단으로 다시 옮겨지는 기능을 추가하기
도전! 03 답
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:srcCompat="@drawable/image01"
android:layout_above = "@+id/button"
android:visibility="visible"
/>
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
app:srcCompat="@drawable/image01"
android:layout_below="@+id/button"
android:visibility="invisible"
/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="70dp"
android:layout_marginStart="70dp"
android:onClick="onButton1Clicked1"
android:gravity="center"
android:text="▲" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginRight="70dp"
android:layout_marginEnd="70dp"
android:onClick="onButton1Clicked2"
android:gravity="center"
android:text="▼" />
</RelativeLayout>
MainActivity.java
package com.example.kai01.doitmission_03;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
ImageView imageView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
imageView2 = (ImageView) findViewById(R.id.imageView2);
}
public void onButton1Clicked1(View v) {
imageView.setVisibility(View.VISIBLE);
imageView2.setVisibility(View.INVISIBLE);
}
public void onButton1Clicked2(View v) {
imageView2.setVisibility(View.VISIBLE);
imageView.setVisibility(View.INVISIBLE);
}
}
동작 화면

도전! 04 SMS 입력 화면 만들고 글자 수 표시하기
프로젝트 소스: DoitMission-04
1. SMS로 문자를 전송하는 화면은 위쪽에 텍스트 입력상자, 아래쪽에 [전송]과 닫기 버튼을 수평으로 배치하도록 구성
2. 텍스트 입력상자 바로 아래에 입력되는 글자의 바이트 수를 “10/80 바이트”와 같은 포맷으로 표시하되 우측 정렬로 하도록 하고 색상을 눈에 잘 띄는 다른 색으로 설정하기
3. 텍스트 입력상자에 입력되는 글자의 크기와 줄 간격을 조정하여 한 줄에 한글 8글자가 들어가도록 만들어 보기
4. [전송] 버튼을 누르면 입력된 글자를 화면에 토스트로 표시하여 내용을 확인할 수 있도록 하기
도전! 04 답
가상키보드 숨기기 설정부터 함

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/editText"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:background="@drawable/border"
android:cursorVisible="true"
android:ems="10"
android:inputType="textMultiLine|textNoSuggestions"
android:textSize="40dp"
/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="110dp"
android:layout_marginEnd="45dp"
android:layout_marginRight="45dp"
android:text="0 / 80 바이트"
android:textColor="#ffff0000"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="40dp"
android:layout_marginStart="60dp"
android:text="전송"
android:layout_alignParentLeft="true"
android:layout_marginLeft="60dp"
android:onClick="onButton1Clicked"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="40dp"
android:layout_marginEnd="60dp"
android:text="닫기"
android:layout_alignParentRight="true"
android:layout_marginRight="60dp" />
</RelativeLayout>
MainActivity.java
package com.example.kai01.doitmission_04;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity {
TextView textView;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(textWatcher); // TextWatcher 리스너 등록
}
// EditText가 눌릴 때마다 감지하는 부분
TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable edit) {
// Text가 바뀌고 동작할 코드
// 그런거 없으니 비움
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Text가 바뀌기 전 동작할 코드
// 그런거 없으니 비움
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// 입력받은 문자의 개수를 센다.
int charCount = editText.getText().toString().length();
// 문자의 개수를 다시 textView에 넣는다.
textView.setText(charCount + " / 80 바이트");
}
};
public void onButton1Clicked(View v) {
Toast.makeText(getApplicationContext(), editText.getText(), Toast.LENGTH_LONG).show();
}
}
동작 화면

- 키보드로 한글 입력하고 싶은데 어떻게 하는지 모르겠음…
Comments