07. 고급 위젯

Download Report

Transcript 07. 고급 위젯

고급 위젯
MCALAB
양평우
1. 프로그래스 바
 프로그래스 바
 프로그래스 바는 작업의 진행 정도를 표시하거나 작업이 진행 중이라는 것을 사
용자에게 보여주는 위젯
 프로그램 설치나 네트워크 다운로드 작업 등에 흔히 사용되며, 결과를 보여주는
방식에 따라 두 가지 타입이 제공
• 원 모양
- 작업의 전체 분량을 미리 알 수 없을 때 사용하며, 동그란 원이 뱅글뱅글 돌아가는 모양으로 작업이 끝나면
애니메이션이 멈춘다.
- 작업이 진행 중이라는 것만 알 수 있으며 디폴트이다.
• 막대 모양
- 작업 분량을 미리 알고 있을 때 사용하며 진척도를 막대 그래프 모양으로 표시한다.
- 스타일 속성을 “?android:attr/progressBarStyleHorizontal”로 지정한다.
 범위는 max 속성으로 지정, 초기값은 progress 속성으로 지정
 두 개의 진행 상태를 동시에 표시 가능, 범위가 둘 다 같을 시 색상이 다르게 표시
 두 번째 위치는 secondaryProgress 속성으로 지정하되, 사용하지 않으려면 초기
위치를 0으로 설정
1. 프로그래스 바
 코드에서 위치 변경 시 아래의 메서드를 사용
void setProgress (int progress)
void setSecondaryProgress (int secondaryProgress)
void incrementProgressBy (int diff)
void incrementSecondaryProgressBy (int diff)
• 절대 위치를 지정할 수 있고, 현재 위치에서 상대적인 위치를 지정 가능
 백그라운드 작업의 상태를 보여주며,
메인 작업이라도 루프 내부에서는 프
로그래스가 갱신되지 않음
 원칙적으로 스레드에서 표시하는 것
이 보통
 progressbar 예제
• 2개의 프로그래스 바와 여섯 개의 버튼 배
치 (길어서 일부 생략)
• 위쪽 : 막대 프로그래스
• 아래쪽 : 원 모양의 프로그래스
(디폴트로 숨겨짐)
progressbar.xml
<?xml version=“1.0” encoding=“utf-8”?>
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=“vertical”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent” >
<ProgressBar
android:id=“@+id/progress”
style=“?android:attr/progressBarStyleHorizontal”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:max=“100”
android:progress=“10”
android:secondaryProgress=“50” />
……
<ProgressBar
android:id=“@+id/progcircle”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:visibility=“invisible” />
……
1. 프로그래스 바
 ProgressBar.java 예제
ProgressBar.java
public class C10_ProgressBar extends Activity {
ProgressBar mProgBar;
ProgressBar mProgCircle;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.c10_progressbar);
mProgBar = (ProgressBar)findViewById(R.id.progress);
mProgCircle = (ProgressBar)findViewById(R.id.progcircle);
}
Button.OnClickListener mClickListener = new view.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.decfirst:
mProgBar.incrementProgressBy(-2);
break;
case R.id.incfirst:
mProgBar.incrementProgressBy(2);
break;
case R.id.decsecond:
mProgBar.incrementSecondaryProgressBy(-2);
break;
case R.id.incsecond:
mProgBar.incrementSecondaryProgressBy(2);
break;
case R.id.start:
mProgCircle.setVisibility(View.VISIBLE);
break;
case R.id.stip:
mProgCircle.setVisibility(View.INVISIBLE);
break;
}
}
};
[ ProgressBar 예제 실행 결과 ]
}
1. 프로그래스 바
 프로그래스 바는 작업중일때만 보이면 됨
• 뷰에 프로그래스 영역을 따로 확보해 놓는 것은 공간 낭비이며 미관상 좋지 않음
 레이아웃에 배치하지 않고, 필요 시 타이틀 바에 프로그래스 바를 표시 가능
• 이 기능을 사용하려면 윈도우에 기능을 요청
boolean Activity.requestWindowFeature (int featureId)
• getWindow().requestFeature()로도 동일한 요청을 할 수 있으며, 인수로 요청할 기능을
전달
• 윈도우의 전체적인 모양과 기능에 영향을 미치므로 반드시 setContentView를 호출하기
전에 먼저 호출해야기능
하며, 초기화될 때 설정되므로 일단 요청된
기능은 취소할 수 없음
설명
FEATURE_INDETERMINATE_PROGRESS
타이틀 바에 원형의 프로그래스를 표시한다.
FEATURE_PROGRESS
타이틀 바에 막대 모양 프로그래스를 표시한다.
1. 프로그래스 바
 타이틀 바의 프로그래스는 범위를 따로 지정할 수 없으며, 디폴트로 0~10000의
범위를 가짐
• 표현하고자 하는 범위를 적당히 나누어 사용
ex) 백분율 표시 : 값 1에 대해 위치 100을 증가
 프로그래스와 관련된 기능 두 가지
• 프로그래스 반투명 표시
requestWindowFeature(Window.FEATURE_PROGRESS);
• 프로그래스의 보이기 상태나 위치값 변경
void setProgressBarVisibility (boolean visible)
void Activity.setProgress (int progress)
1. 프로그래스 바
 ProgressTitle.java 예제
• 레이아웃에 별도의 공간을 차지하지 않고 작업이 진행될 때만 프로그래스를 보일 수 있
으므로 편리
• 작업이 끝나면 프로그래스를 숨김
ProgressTitle.java
public class ProgressTitle extends Activity {
int mProg;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.progresstitle);
mProg = 5000;
setProgress(mProg);
setProgressBarVisibility(true);
findViewById(R.id.decfirst).setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (mProg >= 200) mProg -= 200;
setProgress(mProg);
}
});
findViewById(R.id.incfirst).setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (mProg <= 9800) mProg += 200;
setProgress(mPfog);
}
});
}
}
[ ProgressTitle 예제 실행 결과 ]
1. 프로그래스 바
 타이틀 바에 원 모양 애니메이션을 표시할 경우 아래 형식으로 윈도우의 기능을
요청
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
 두 플래그가 상호 배타적이어서 막대 모양과 원 모양을 동시에 표시할 수 없음
 원 모양 프로그래스 바는 범위나 위치의 개념이 없으며 보이거나 숨기기만 가능
void Activity.setProgressBarIndeterminateVisibility(boolean visible)
• 보이기 상태
변경 시 아래의 메서드를 호출
• 타이틀 바의 오른쪽에 나타나며 표시되는 동안 애니메이션이 계속 재생
ProgressTitle2.java
public class ProgressTitle2 extends Activity {
int mProg;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.progresstitle2);
findViewById(R.id.start).setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
setProgressBarIndeterminateVisibility(true);
}
});
findViewById(R.id.stop).setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
setProgressBarIndeterminateVisibility(false);
}
});
}
}
[ ProgressTitle2 예제 실행 결과 ]
1. 프로그래스 바
 시크 바 (SeekBar)
 프로그래스 위젯을 확장한 서브 클래스로, 사용자가 값을 직접 조정 가능
• 볼륨이나 동영상 재생 위치처럼 정확한 값보다는 대충의 값을 신속하게 조정할 때 적합
• 키패드로 조정하는 경우는 드물고 대부분 화면을 터치하여 조정하기 때문에 주변에 가
급적이면 터치 입력을 받는 다른 위젯을 배치하지 않는 것이 좋음
 프로그래스 바의 파생 위젯이므로 속성도 그대로 물려받음
• max : 범위의 최대값
• progress : 현재 위치
• secondaryProgress : 두 번째 위치를 지정 (사용자가 조작 불가능)
 시크 바만의 고유 속성
• thumb : 썸 모양을 별도의 이미지로 장식 가능 (디폴트가 무난함)
 사용자가 시크 바를 조작하면 값이 변하고, OnSeekBarChangeListener 인터페이
스의 리스너들이 호출
void onStartTrackingTouch (SeekBar seekBar)
void onStoptrackingTouch (SeekBar seekBar)
void onProgressChanged (SeekBar seekBar, int progress, boolean fromUser)
• 터치를 시작하거나 끝낼 때 특별한 처리가 필요할 때 사용하며, 가장 실용적인 것은 위
치값이 변할 때인데 변경된 위치에 맞게 값을 조정
1. 프로그래스 바
 SeekBar.java 예제
• 트래킹을 시작할 때와 끝날 때에 대한 리스너는 따로 구현 안 함
• 인터페이스가 요구하는 메서드이므로 설사 본체가 비어있어도 메서드는 구현해야 함
seekbar.xml
SeekBar.java
<?xml version=“1.0” encoding=“utf-8”?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:orientation=“vertical”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent” >
<SeekBar
android:id=“@+id/seekbar”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:max=“100”
android:progress=“50” />
<TextView
android:id=“@+id/volume”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:text=“Now volume : 50” />
</LinearLayout>
Public class SeekBar extends Activity {
SeekBar mSeekBar;
TextView mVolume;
public void onCreate(Bundle savedInstanceState) {
super.OnCreate(savedInstanceState);
setContentView(R.layout.seekbar);
[ C10_SeekBar 예제 실행 결과 ]
mSeekBar = (SeekBar)findViewById(R.id.seekbar);
mVolume = (TextView)findViewById(R.id.volume);
mSeekBar.setOnSeekBarChangeListener(new
SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mVolume.setText(“Now volume : “ + progress);
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
1. 프로그래스 바
 래이팅 바 (RatingBar)
 별점을 표시하거나 입력 받는 위젯
• 만점을 기준으로 얼마만큼 점수를 받았는가를 표시
• 값을 조정할 수 있으며 읽기 전용 속성을 지원
• 영화나 서적 등에 별의 개수로 선호도를 매기는데 이런 점수 표시 및 입력용으로 흔히
사용
 Rating.java 예제
Rating.java
Public class Rating extends Activity {
RatingBar mRating;
TextView mRateText;
public void onCreate(Bundle savedInstanceState) {
super.OnCreate(savedInstanceState);
setContentView(R.layout.rating);
mRating= (RatingBar)findViewById(R.id.ratingbar);
mRateText = (TextView)findViewById(R.id.ratetext);
mRating.setOnRatingBarChangeListener(new
RatingBar.OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
mRateText.setText(“Now Rate : “ + rating);
}
});
}
}
1. 프로그래스 바
• numStar : 만점이 되는 별의 개수
- 임의의 개수 지정 가능. (디폴트 5)
- 별의 개수에 따라 위젯의 폭 결정.
- 레이아웃의 위젯 폭은 반드시 wrap_content
로 지정해야 함.
• stepSize : 별점의 조정 단위
- 1 : 별 1개 단위로 점수를 매김
- 0.5 : 별 반개 단위로 점수를 매김
- 0.1 : 정밀히 점수 매김 가능
- 한 개 단위는 해상도가 떨어지므로 보통 반 개
단위가 많으며 디폴트는 0.5
• rating : 초기 별점 (디폴트 0)
• isIndicator
: 별점을 단순히 표시만 할 것인지를 지정
- 디폴트 false
- ratingBarStyleIndicator
: 별점 표시만 가능 (사용자 조정 불가능)
- ratingBarStyleSmall
: 별이 작게 표시됨 (읽기 전용)
rating.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RatingBar
android:id="@+id/ratingbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stepSize="0.2"
android:rating="3" />
<TextView
android:id="@+id/ratetext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Now Rate : 3" />
<RatingBar
android:id="@+id/ratingbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rating="2"
android:isIndicator="true" />
<RatingBar
style="?android:attr/ratingBarStyleIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="4"
android:rating="2.5" />
<RatingBar
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="10"
android:rating="7" />
</LinearLayout>
• 사용자가 별점을 드래그해 조정하면 OnRatingBarchangeListener 인터페이스의
onRatingChanged 리스너가 호출되어 변경된 별점을 읽고 처리
2. 날짜와 시간
 날짜 시간
 System의 정적 메서드 이용
static long currentTimeMillis ()
• 현재 시간값을 정수 하나로 리턴
• 에폭 타임(Epoch Time) 기준
- 1970년 1월 1일 자정을 기준으로 한 1/1000초 단위의 경과 시간
- 년, 월, 일, 시, 분, 초의 요소들을 개별적이 아닌 단 하나의 값으로 일차원화하여 표현하므로 전달, 저장,
비교가 용이함
- 출력용으로는 적합하지 않음
 Date 클래스
• 날짜와 관련된 기본 클래스로 시간도 함께 표현함
• Time 클래스는 따로 제공되지 않음
• 생성자는 6개이며, 각 요소를 개별적으로 지정 또는 에폭 타임으로 초기화할 수 있음
Date (int year, int month, int day [, int hour, int minute, int second])
Date (long milliseconds)
2. 날짜와 시간
 Calendar 클래스
• 날짜를 표현하는 고급 클래스
• 생성자는 동기화의 문제로 외부에서 호출할 수 없도록 감추어져 있음
• getInstance 정적 메서드로 객체를 생성
• 시간대와 지역 설정을 전달받아 현재 시간으로 초기화하되 두 인수 모두 생략 시 시스
템 설정을 따름
static synchronized Calendar getInstance ([TimeZone timezone, Locale locale])
• 날짜, 시간을 구성하는 개별 요소는 아래의 메서드로 분리하거나 설정
int get (int field)
void set (int field, int value)
void set (int year, int month, int day, int hourOfDay, int minute, int second)
void add (int field, int value)
• Date 객체나 에폭 타임과 상호 변환 가능
Date getTime ()
void setTime (Date date)
void setTimeInMillis (long milliseconds)
long getTimeInMillis ()
2. 날짜와 시간
 GregorianCalendar 클래스
• Calendar의 서브 클래스로 실제 프로젝트에서 사용됨
• 윤년에 대한 정교한 규칙이 추가되어 있으며 태양력을 표현
• 요소 지정 및 시간대, 지역 설정을 전달할 수 있으나 디폴트 생성자 호출 시 시스템 설정
을 참조하여 현재 시간으로 초기화됨
GregorianCalendar (int year, int month, int day, int hour, int minute, int second)
GregorianCalendar (TimeZone timezone, Locale locale)
• 날짜를 사용자에게 보여주기 위해 문자열 형태로 변환
• Date 객체나 Calendar 객체의 toString 메서드로 변환 가능하나, 영문 약자로 변환되고 포맷
이 고정적임
• 날짜 포맷 클래스를 사용하여 자유로운 형태로 포맷팅
SimpleDateFormat (String pattern)
String format (Date date)
- 패턴 문자열에 y, m, d 등의 기호로 각 시간 요소의 위치와 포맷을 설정하고 format 메서드를 호출하여
패턴대로 변환
- 패턴의 종류는 레퍼런스 참조
• DateUtils 클래스도 포맷팅 기능을 제공하나 영문으로 나오며, 경과 시간은 시간 단위까지만
변환되어 활용도가 떨어짐
2. 날짜와 시간
 SystemClock 클래스
• 안드로이드의 날짜 지원 클래스
static long elapsedRealtime ()
static long uptimeMillis ()
static long currentThreadTimeMillis ()
 C10_DateTime.java 예제
DateTime.java – 1
public class DateTime extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datetime);
Refresh();
}
public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btnrefresh:
Refresh();
break;
}
}
void Refresh() {
StringBuilder time = new StringBuilder();
long epoch = System.currentTimeMillis();
time.append("epoch = " + epoch + "\n");
//time.append("now = " + DateUtils.formatDateTime(this, epoch, 0) +
"\n");
Calendar cal = new GregorianCalendar();
time.append("now = " + String.format("%d년 %d월 %d일 %d시 %d분
\n", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DAY_OF_MONTH),
cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)));
2. 날짜와 시간
 DateTime.java 예제
DateTime.java – 2
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd
hh:mm:ss");
time.append("now = " + sdf.format(now) + "\n");
Calendar tom = new GregorianCalendar();
tom.add(Calendar.DAY_OF_MONTH, 1);
Date tomdate = tom.getTime();
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd");
time.append("tomorrow = " + sdf2.format(tomdate) + "\n");
time.append("boot = " + UpTime(SystemClock.elapsedRealtime()));
time.append("run = " + UpTime(SystemClock.uptimeMillis()));
time.append("thread = " + UpTime(
SystemClock.currentThreadTimeMillis()));
TextView result = (TextView)findViewById(R.id.result);
result.setText(time.toString());
}
String UpTime(long msec) {
long sec = msec / 1000;
String result;
result = String.format("%d일 %d시 %d분 %d초\n", sec / 86400,
sec / 3600 % 24, sec / 60 % 60, sec % 60);
//result = DateUtils.formatElapsedTime(sec) + "\n";
return result;
}
}
2. 날짜와 시간
 시계 위젯
 DigitalClock
• 숫자 형태로 시간을 표시
• 초단위까지 표기되며 매초마다 자동으로 갱신
• TextView의 서브 클래스이므로 글꼴 크기, 색상 등은 변경 가능하나 텍스트의 내용 자
체는 변경할 수 없음
• 추가적인 속성이나 메서드는 없으며, 시간대, 지역 설정, 시간의 포맷은 시스템 설정값
을 따름
 AnalogClock
• 시침, 분침이 있는 바늘 시계를 보여주며 초침은 표시되지 않음
• 시간 갱신은 분단위로 이루어지며 초 단위의 변화에 대해서는 반응 없음
※ 두 위젯 모두 현재 시간을 보여주기만 할 뿐, 임의의 시간으로 변경 불가능
※ 생성자 외에는 공개된 메서드가 없으며 레이아웃에 배치해 두면 알아서 동작함
2. 날짜와 시간
 clock.xml 예제
clock.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent“
android:gravity="center_horizontal" >
<AnalogClock
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<DigitalClock
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10pt"
android:textColor="#00ff00" />
</LinearLayout>
public class Clock extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clock);
}
}
2. 날짜와 시간
 날짜, 시간 입력기
 DatePicker 위젯
• 터치만으로 날짜와 시간을 입력받는 위젯
• 년, 월, 일을 각각의 버튼으로 보여주고 아래위의 증감 버튼을 눌러 값을 조정
• 년, 월, 일의 순서는 장비의 로케일 설정을 따름
• 크기가 고정되어 있어 폭과 높이는 의미가 없으므로 항상 wrap_content로 지정
• 날짜를 설정하거나 조사 시 아래의 메서드를 호출
void updateDate (int year, int monthOfYear, int dayOfMonth)
int getYear ()
int getMonth ()
getDayOfMonth ()
• updateDate 메서드로 첫 날짜를 초기화하며 get* 메서드로 사용자가 조정한 값을 조사
• 값이 변경될 때마다 통지를 받기 위해 이벤트 핸들러를 등록
• 리스너 등록 메서드가 updateDate 기능을 겸함
void init (int year, int monthOfYear, int dayOfMonth,
DatePicker.OnDateChangedListener onDateChangedListener)
2. 날짜와 시간
• 사용자가 날짜 편집 시 리스너의 메서드가 호출되어 현재 편집된 값을 알려줌
- monthOfYear는 제로 베이스(zero base)이며, 1월이 0부터 시작
void onDateChanged (DatePicker view, int year, int monthOfYear, int dayOfMonth)
 TimePicker 위젯
• 시간을 입력 받으며 특별한 속성 없이 배치하면 자동으로 동작함
• 시간과 분만 입력받으며 초단위는 입력받지 못함
• 오전/오후 선택 가능
• 아래의 메서드로 시간을 설정하거나 조사함
void setCurrentHour (Integer currentHour)
void setCurrentMinute (Integer currentMinute)
Integer getCurrentHour ()
Integer getCurrentMinute ()
• 시간은 24시간제로 표현 가능하며 AM/PM 방식의 12시간제로도 표현 가능 (디폴트는 12시간
제)
• 아래의 메서드로 방식을 조사 및 변경함
boolean is24HourView ()
void setIs24HourView (Boolean is24HourView)
2. 날짜와 시간
• 시간 편집 시 이벤트는 아래의 메서드로 지정
- 리스너의 핸들러로 편집된 시간과 분이 전달
- DatePicker에 비해 핸들러 지정 방법이 합리적으로 설계됨
void setOnTimeChangedListener (TimePicker.OnTimeChangedListener onTimeChangedListener)
void onTimeChanged (TimePicker view, int hourOfDay, int minute)
 DateTimePicker.java 예제
DateTimePicker.java – 1
public class DateTimePicker extends Activity {
DatePicker mDate;
TextView mTxtDate;
TimePicker mTime;
TextView mTxtTime;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datetimepicker);
// 날짜 선택기
mDate = (DatePicker)findViewById(R.id.datepicker);
mTxtDate = (TextView)findViewById(R.id.txtdate);
mDate.init(mDate.getYear(), mDate.getMonth(),
mDate.getDayOfMonth(),
new DatePicker.OnDateChangedListener() {
public void onDateChanged(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
mTxtDate.setText(String.format("%d/%d/%d", year,
monthOfYear + 1, dayOfMonth));
}
}
);
2. 날짜와 시간
 DateTimePicker.java 예제
DateTimePicker.java – 2
// 시간 선택기
mTime = (TimePicker)findViewById(R.id.timepicker);
mTxtTime = (TextView)findViewById(R.id.txttime);
mTime.setOnTimeChangedListener(
new TimePicker.OnTimeChangedListener()
{
public void onTimeChanged(TimePicker view, int hourOfDay,
int minute) {
mTxtTime.setText(String.format("%d:%d", hourOfDay,
minute));
}
});
// 24시간제 토글
findViewById(R.id.btntoggle24).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
mTime.setIs24HourView(!mTime.is24HourView());
}
});
// 선택기로부터 날짜 조사
findViewById(R.id.btnnow).setOnClickListener(new
View.OnClickListener()
{
public void onClick(View v) {
String result = String.format("%d/%d/%d %d:%d",
mDate.getYear(), mDate.getMonth() + 1,
mDate.getDayOfMonth(), mTime.getCurrentHour(),
mTime.getCurrentMinute());
Toast.makeText(C10_DateTimePicker.this, result, 0).show();
}
});
}
}
2. 날짜와 시간
 PickerDialog.java 예제
• DatePickerDialog, TimePickerDialog 위젯은 동일한 기능을 수행하되 필요한 때만 대화
장자를 열여 값을 입력 받음
• onCreate에서 현재 시간과 날짜를 멤버에 조사하여 텍스트 뷰에 출력
• 값 변경 시 날짜, 시간 대화상자를 각각 호출하며, 대화상자 호출 전에 생성자로 현재 값
을 전달, 대화상자가 닫힐 때 편집된 값을 돌려 받음
• 편집 취소 시 리스는 호출되지 않음
• 소스 참조
2. 날짜와 시간
 Chronometer
 경과 시간을 측정하는 일종의 스톱워치
• 생성 직후부터의 경과 시간을 MM:SS 포맷으로 표시하며, 1시간이 넘어가면 시간 단위
도 생김
• 시간 외의 정보 출력 시 format 속성에 지정하되 문자열 사이에 %s 서식을 넣어두면 이
자리에 H:MM:SS 형태의 현재 시간이 삽입됨
• 기준 시간은 생성 시간이되 아래의 메서드로 변경 가능
void setBase (long base)
- 인수로 부팅 후의 경과 시간을 전달
- 보통 현재 시간부터 카운팅을 시작하므로 elapsedRealtime 메서드로 구한 경과 시간을 전달
- start 메서드 : 시간 갱신 시작
- stop 메서드 : 시간 갱신을 잠시 중지
- setBase 호출 후 start를 호출하면 0초부터 시간이 카운트되며 매초마다 시간은 자동으로 갱신
※ start, stop 메서드는 시간의 갱신 여부만을 통제할 뿐 타이머의 카운트 자체를 제어하지 않음
2. 날짜와 시간
 Chronometer.java 예제
Chronometer.java
public class Chronometer extends Activity {
Chronometer mChrono;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.c10_choronometer);
mChrono = (Chronometer)findViewById(R.id.chrono);
}
public void onDestroy() {
super.onDestroy();
mChrono.stop();
}
public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btnstart:
mChrono.start();
break;
case R.id.btnstop:
mChrono.stop();
break;
case R.id.btnreset:
mChrono.setBase(SystemClock.elapsedRealtime());
break;
}
}
}
<Chronometer
android:id="@+id/chrono"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format="경과시간=%s"
android:textSize="30sp"
/>
2. 날짜와 시간
 Chronometer의 문제점
• 크로노미터는 start 호출 직후부터 타이머 핸들러를 실행하며, 이상태로 종료 시 리소스
릭이 발생하므로 종료 전 반드시 stop을 호출해야 함
• 시간이 경과할 때마다 신호를 받고 싶으면 OnChronometerTickListener 리스너를 등록
할 수 있으나 이런 목적으로는 핸들러가 더 간편함
• 최소 시간은 초단위이며, 해상도가 떨어져 정밀한 스톱워치로 활용하기 어려움
 StopWatch.java 예제
• 제대로 동작하는 스톱워치를 만들기 위해서는 핸들러를 직접 돌리며 1/100초 단위까지
카운팅해야 함
• 중간 기록, 재시작, 초기화 등의 부가 기능을 추가
• 소스 참조
3. 기타 위젯
 자동 완성
 AutoCompleteTextView
• 자동 완성 기능을 제공하는 에디트
• EditText의 서브 클래스로 모양이나 기능은 에디트와 동일함
• 단어의 일부만 입력하면 후보 문자열을 드롭 다운으로 보여 주고 그 중 하나를 빠르게
선택할 수 있음
- 모바일 환경은 입력장치가 불편하므로 입력 속도를 높이기 위해 후보 목록을 보여주는 방식을 지원함
- 후보 문자열은 어댑터로부터 받음
• 후보 목록을 미리 구해 놓고 아래의 메서드로 어댑터에 전달하면 목록 내의 문자열을
후보로 활용함
void setAdapter (T adapter)
• completionThreshold 속성
- 몇 자까지 입력했을 때 후보 목록을 보여줄 것인가를 지정
- 디폴트는 2자로 되어있으며, 한글 음소 단위로는 동작하지 않음
• completionHint 속성
- 후보 목록 아래쪽에 표시할 도움말 문자열 지정
• 에디트 아래쪽에 에디트와 같은 폭으로 열리며 dropDownAnchor, dropDownHeight,
dropDownWidth, dropDownHorizontalOffset, dropDownVerticalOffset 등의 속성을 변경하여
위치나 크기 조정
3. 기타 위젯
 AutoComplete.java 예제
AutoComplete.java
public class AutoComplete extends Activity {
String[] arWords = new String[] {
"가구", "가로수", "가방", "가슴", "가치", "가훈", "나그네", "다리미",
"above", "about", "absolute", "access", "activity", "adjust"
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.autocomplete);
ArrayAdapter<String> adWord = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, arWords);
AutoCompleteTextView autoEdit = (AutoCompleteTextView)
findViewById(R.id.autoedit);
autoEdit.setAdapter(adWord);
}
}
<AutoCompleteTextView
android:id="@+id/autoedit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:completionHint
="목록에서 원하는 단어를 탭하십시오."
/>
3. 기타 위젯
 MultiAuto.java 예제
C10_MultiAuto.java
public class MultiAuto extends Activity {
String[] arWords = new String[] {
"가구", "가로수", "가방", "가슴", "가치", "가훈", "나그네", "다리미",
"above", "about", "absolute", "access", "activity", "adjust"
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multiauto);
ArrayAdapter<String> adWord = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, arWords);
MultiAutoCompleteTextView autoEdit = (MultiAutoCompleteTextView)
findViewById(R.id.autoedit);
autoEdit.setAdapter(adWord);
autoEdit.setTokenizer(new
MultiAutoCompleteTextView.CommaTokenizer());
}
}
3. 기타 위젯
 SlidingDrawer
 슬라이딩 되는 서랍
• 평소에는 벽 한쪽에 숨어 있다가 손잡이를 끌거나
누르면 밖으로 튀어나옴
• 2.1 이전의 에뮬레이터에서 메인 메뉴가 서랍으로
되어 있으며, 서랍 안쪽에 설치된 프로그램 목록
이 나타남
• 2.1에서는 버튼 형태로 바뀌었고 실장비에서도 다
른 종류의 메뉴가 사용됨
• 펼칠 때 다른 뷰 위에 포개어 나타나므로 차일드
끼리 겹칠 수 있는 레이아웃에만 배치 가능
• 프레임이나 렐러티브 정도가 적합함
• 핸들과 내용이라는 두 개의 주요 뷰로 구성
- 핸들 : 서랍을 꺼내고 넣는 이미지 뷰로 항상 보임
- 내용 : 서랍을 꺼냈을 때 나타날 임의의 레이아웃으로 다른
차일드를 넣을 수 있음
3. 기타 위젯
 서랍의 주요 속성
기능
설명
handle
서랍의 손잡이로 사용할 뷰이다. 통상 이미지 뷰를 사용한다
content
서랍의 내용 레이아웃이다. 임의의 레이아웃을 사용할 수 있으며 스크롤도
가능하다.
orientation
서랍의 방향이다. 수직이면 아래쪽에서 위로 열리며 수평이면 오른쪽에서
왼쪽으로 열린다. 반대 방향은 지원하지 않는다.
topOffset
서랍을 완전히 꺼냈을 때 핸들과 부모 위쪽 변과의 간격이다. 디폴트는 0이
어서 서랍이 부모를 완전히 덮는다.
bottomOffset
서랍을 닫았을 때 핸들과 부모 아래쪽과의 간격이다. 핸들이 너무 높다면 이
값을 적당히 주어 조금 더 아래쪽으로 숨길 수 있다.
allowSingleTap
핸들을 탭하여 서랍을 열고 닫을 수 있도록 한다. 디폴트는 true이되 false로 변
경하면 드래그해야만 서랍을 열 수 있다.
animateOnClick
클릭하여 서랍을 열 때 미끄러지는 듯한 애니메이션을 한다. 디폴트는 true이
다.
• open, close, toggle 메서드 : 서랍을 열고 닫거나 토글함
• animateOpen, animateClose, animateToggle 메서드 : 애니메이션과 함께 서랍을 열고 닫음
• isOpened 메서드 : 서랍이 열려 있는지 조사
• lock, unlock 메서드 : 사용자의 터치 동작을 잠그거나 해제
• 서랍이 열리거나 닫힐 때 특정 처리 시 setOnDrawerOpenListener,
setOnDrawerCloseListener 리스너 등록
3. 기타 위젯
 SlidingDrawer.java 예제
SlidingDrawer.java
public class SlidingDrawer extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slidingdrawer);
}
public void mOnClick(View v) {
SlidingDrawer drawer = (SlidingDrawer)findViewById(R.id.drawer);
drawer.animateClose();
}
}
slidingdrawer.xml
<?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="아래쪽의 핸들을 드래그하세요." />
<SlidingDrawer
android:id="@+id/drawer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:topOffset="60dip"
android:handle="@+id/handle"
android:content="@+id/content">
<ImageView
android:id="@id/handle"
android:src="@drawable/andexam"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@id/content"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#808080" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:text="여기는 서랍의 안쪽입니다." />
<Button
android:id="@+id/closedrawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="서랍 닫기" />
</LinearLayout>
</SlidingDrawer>
</RelativeLayout>
3. 기타 위젯
 ScrollView
 수직 스크롤 기능을 제공하는 뷰
• 현재 스크롤 위치의 내용을 보여주되 손가락으로 화면을 빠르게 문지르는 플리킹 동작
이나 방향키 입력을 받아 다른 부분으로 신속하게 이동할 수 있음
• 리스트 뷰나 에디트 뷰도 내용물이 클 수 있으므로 고유의 스크롤 기능을 제공
- 리스트 뷰의 항목 개수에 제한이 없으며 에디트 뷰는 긴 문자열 표시 가능
- 이 두 위젯은 스크롤 뷰와 함께 사용할 필요 없음
• FrameLayout의 서브 클래스로 단 하나의 차일드만 가질 수 있으나 컨테이너 배치 시
그 안에 다른 뷰를 배치할 수 있음
<ScrollView>
<LinearLayout>
<Widget>
<Widget>
<Widget>
...
</LinearLayout>
</ScrollView>
• 정적인 레이아웃보다 실행 중 내용물의 길이가 가변적으로 결정되는 동적 레이아웃에 주로
사용됨
3. 기타 위젯
 ScrollView.java 예제
scrollview.xml
ScrollView.java
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scr"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ScrollView>
public class ScrollView extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scrollview);
ScrollView svw = (ScrollView)findViewById(R.id.scr);
//svw.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
//svw.setVerticalFadingEdgeEnabled(false);
//svw.setVerticalScrollBarEnabled(false);
svw.addView(new ColorView(this));
}
}
class ColorView extends View {
public ColorView(Context context) {
super(context);
}
public void onDraw(Canvas canvas) {
Paint Pnt = new Paint();
for (int y = 0;y < 1280;y += 5) {
Pnt.setARGB(255, 255 - y / 5, 255 - y / 5, 255);
canvas.drawRect(0, y, 1280, y + 5, Pnt);
}
}
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
setMeasuredDimension(1280, 1280);
}
}
3. 기타 위젯
 스크롤 뷰 동작 지정 메서드
• ScrollView의 메서드가 아닌 View의 메서드
• 모든 뷰는 스크롤 여부에 상관없이 아래의 메서드를 호출할 수 있음
void setScrollBarStyle (int style)
 스크롤 바의 스타일 지정
• ScrollView의 메서드가 아닌 View의 메서드
• 모든 뷰는 스크롤 여부에 상관없이 아래의 메서드를 호출할 수 있음
기능
설명
SCROLLBARS_INSIDE_OVERLAY
패딩 추가없이 내용물의 안쪽에 배치한다. 내용물 위에 투명하
게 얹힌다. 이 값이 디폴트이다.
SCROLLBARS_INSIDE_INSET
패딩을 추가하고 패딩에 스크롤바를 배치한다. 내용물 위에 오
버랩되지 않는다.
SCROLLBARS_OUTSIDE_OVERLAY
패딩 추가없이 가장자리에 배치한다. 내용물 위에 투명하게 얹
힌다.
SCROLLBARS_OUTSIDE_INSET
패딩을 추가하고 가장자리에 배치한다.
3. 기타 위젯
• 스크롤 중에 가장자리가 흐릿해지는 효과를 적용할 것인지와 음영 길이를 지정
void setVerticalFadingEdgeEnabled (boolean verticalFadingEdgeEnabled)
void setHorizontalFadingEdgeEnabled (boolean horizontalFadingEdgeEnabled)
void setFadingEdgeLength (int length)
• 스크롤 바를 사용할 것인가 아닌가를 지정
void setVerticalScrollBarEnabled (boolean verticalScrollBarEnabled)
void setHorizontalScrollBarEnabled (boolean horizontalScrollBarEnabled)
 HScrollView.java 예제
HScrollView.java
public class HScrollView extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hscrollview);
HorizontalScrollView svw = (HorizontalScrollView)findViewById(R.id.scr);
svw.addView(new HColorView(this));
}
}
class HColorView extends View {
public HColorView(Context context) { super(context); }
public void onDraw(Canvas canvas) {
Paint Pnt = new Paint();
for (int x=0;x<1024;x+=4) {
Pnt.setARGB(255,255-x/4,255-x/4,255);
canvas.drawRect(x,0,x+4,500,Pnt); }
}
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(1024, 500); }
}
3. 기타 위젯
 WebView
 웹 페이지를 보여주는 위젯
• 네트워크 입출력, 캐싱, 링크 클릭 처리, 확대, 축소, 히스토리 관리 등 웹 브라우저가 제
공하는 모든 기능을 자체적으로 제공
• 안드로이드에 내장된 웹킷(WebKit) 라이브러리가 처리하므로 원하는 곳에 배치한 후
주소를 넘겨주면 동작함
- 웹킷은 오픈 소스이며 사파리, 크롬 등에 채용되어 성능이 입증됨
• 인터넷 엑세스를 위해 권한이 필요함
- 요금 문제와 관련되므로 반드시 사용자의 허가나 동의가 필요함
• 웹을 사용하는 프로그램은 매니페스트에 INTERNET 퍼미션을 반드시 지정해야 함
<uses-permission android:name="android.permission.INTERNET" />
• 웹뷰를 사용하여 간단한 웹 브라우저를 만들 수 있으며 액티비티의 일부에 웹 페이지 표시 가
능
WebView.java
3. 기타 위젯
 WebView.java 예제
public class WebView extends Activity {
WebView mWeb;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
mWeb = (WebView)findViewById(R.id.web);
mWeb.setWebViewClient(new MyWebClient());
WebSettings set = mWeb.getSettings();
set.setJavaScriptEnabled(true);
set.setBuiltInZoomControls(true);
mWeb.loadUrl("http://www.google.com");
}
public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btngo:
String url;
EditText addr = (EditText)findViewById(R.id.address);
url = addr.getText().toString();
mWeb.loadUrl(url);
break;
case R.id.btnback:
if (mWeb.canGoBack()) {
mWeb.goBack();
}
break;
case R.id.btnforward:
if (mWeb.canGoForward()) {
mWeb.goForward();
}
break;
case R.id.btnlocal:
mWeb.loadUrl("file:///android_asset/test.html");
break;
}
}
class MyWebClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
}
}
3. 기타 위젯
 웹뷰의 설정 변경
• getSetting 메서드로 WebSettings 객츠를 얻은 후 이 객체의 set* 메서드로 캐시 정
책, 폰트 크기, 확대 여부, 스크립트 허용 여부 등의 설정 변경 가능
• 디폴트가 무난하나 몇 가지 설정은 꼭 변경해야 함
- 자바 스크립트는 필수적
- 내장 확대 기능을 사용할 경우 아래쪽에 확대, 축소 버튼이 나타나 사용자가 직접 배율 조절 가능하여 편리함
• 히스토리의 앞, 뒤 이동 기능 제공 메서드
void goBack ()
void goForward ()
boolean canGoBack ()
boolean canGoForward ()
 웹뷰는 로컬의 HTML 파일도 표시 가능
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title>Test Html</title>
</head>
<body>
<h2>Test Web Page</h2>
<span style="COLOR:#ff0000;">빨간색 글자</span><br />
<a href="http://www.microsoft.com">Microsoft.com</a>
</body>
3. 기타 위젯
 스포츠 경기 점수판
 SportsScore.java 예제
• 스포츠 경기의 점수를 매기는 것을 도와주는 앱
• 점수를 매기는 불편함을 해소해주는 간단한 카운터