728x90
반응형
Android 앱 개발에서 타이머 기능은 생각보다 자주 쓰이는 기능입니다. 이번 글에서는 알람 소리와 함께 애니메이션이 적용된 귀여운 타이머 앱을 만들어보며, CountDownTimer, MediaPlayer, 애니메이션(YoYo) 라이브러리, SharedPreferences까지 모두 실습해봅니다.
안녕하세요 😊 오늘은 Android Studio를 활용해 간단한 타이머 앱을 만들며 View 배치, 입력 처리, 타이머 로직, 애니메이션, 알람 사운드까지 실습해보는 시간을 가질게요!
앱 목표
- 타이머 시간(초)을 입력받아 시작
- 남은 시간 표시
- 타이머 종료 시 시계 흔들림 + 알람 소리 출력
- 취소 / 종료 / 재시작 기능까지 포함!
1. 전체 레이아웃 구성
1-1. 시계 이미지 (ImageView)
<ImageViewandroid:id="@+id/imgClock"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_marginTop="16dp"
android:contentDescription="알람"
android:src="@drawable/alarm_clock"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"/>
- 중심 정렬 + 300dp 크기 설정
1-2. 남은 시간 표시 (TextView)
<TextViewandroid:id="@+id/txtTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="남은시간"
android:textSize="30sp"
android:textStyle="bold"
android:textColor="@android:color/black"
app:layout_constraintTop_toBottomOf="@id/imgClock"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"/>
- 시계 아래에 배치, 강조된 글씨체
1-3. 타이머 시간 입력 필드 (EditText + TextInputLayout)
<com.google.android.material.textfield.TextInputLayoutandroid:id="@+id/textInputLayoutTimer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="30dp"
app:layout_constraintTop_toBottomOf="@id/txtTime"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_default="spread">
<com.google.android.material.textfield.TextInputEditTextandroid:id="@+id/editTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="타이머시간(초)"
android:inputType="number"
android:textSize="20sp"
android:textColor="@android:color/black"/>
</com.google.android.material.textfield.TextInputLayout>
- 사용자가 직접 초 단위를 입력할 수 있게 구성
1-4. 버튼 3종 배치 (취소, 시작, 종료)
<LinearLayoutandroid:id="@+id/buttonLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@id/textInputLayoutTimer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.button.MaterialButtonandroid:id="@+id/btnCancel"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:text="타이머 취소"
android:layout_marginEnd="8dp"/>
<com.google.android.material.button.MaterialButtonandroid:id="@+id/btnStart"
style="@style/Widget.MaterialComponents.Button"
android:text="타이머 시작"/>
<Buttonandroid:id="@+id/btnEndAlarm"
android:text="시간 종료"
android:visibility="gone"/>
</LinearLayout>
- 종료 버튼은 기본적으로 숨겨져 있다가 타이머 완료 시 보이게 설정
2. Java 코드 구현 (MainActivity.java)
2-1. 주요 변수 및 뷰 초기화
ImageView imgClock;
TextView txtTime;
EditText editTime;
Button btnCancel, btnStart, btnEndAlarm;
CountDownTimer countDownTimer;
MediaPlayer mediaPlayer;
Handler handler = new Handler();
SharedPreferences sharedPreferences;
2-2. 타이머 시작 로직
protected void startTimer() {
String strTime = editTime.getText().toString().trim();
if (strTime.isEmpty()) {
Toast.makeText(this, "초를 입력하세요.", Toast.LENGTH_SHORT).show();
return;
}
int time = Integer.parseInt(strTime);
long countTime = time * 1000;
btnStart.setEnabled(false);
btnCancel.setEnabled(true);
editTime.setEnabled(false);
countDownTimer = new CountDownTimer(countTime, 1000) {
public void onTick(long millisUntilFinished) {
txtTime.setText(String.valueOf(millisUntilFinished / 1000));
}
public void onFinish() {
txtTime.setText("시간 종료!");
playAlarmAndShakeImage();
btnEndAlarm.setVisibility(View.VISIBLE);
}
}.start();
}
3. 알람 사운드 & 애니메이션 효과
MediaPlayer + YoYo 라이브러리
mediaPlayer = MediaPlayer.create(this, R.raw.alarm);
mediaPlayer.start();
YoYo.with(Techniques.Shake)
.duration(400)
.repeat(4)
.playOn(imgClock);
알람 정지 시 mediaPlayer.release()를 반드시 호출하여 메모리 누수 방지.
4. SharedPreferences로 시간 저장
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(KEY_TIME, time);
editor.apply();
- 앱 재실행 시 마지막에 설정한 시간이 그대로 표시되도록 구현
5.동작 흐름 요약
- 사용자가 시간을 입력하고 "타이머 시작" 버튼 클릭
- 1초 단위로 남은 시간이 TextView에 표시됨
- 종료 시:
- "시간 종료!" 텍스트
- 알람 소리 + 흔들리는 시계 애니메이션
- "종료 버튼" 활성화
6. 예시 시나리오
- 타이머 시작 전 EditText에 초 단위로 입력
- 종료 시 흔들리는 시계 + 알림 소리 출력
- 버튼을 눌러 타이머 중지, 재시작, 종료 가능
마무리 팁
- CountDownTimer는 앱이 백그라운드로 전환되면 정확도가 낮아질 수 있으므로, 백그라운드 상태 저장 기능은 추가 구현 필요
- MediaPlayer는 중첩되지 않도록 재생 전 stop() + release() 권장
- YoYo 라이브러리와 같이 애니메이션 효과를 주면 사용자 경험이 확 살아남✨
728x90
반응형
'Frontend > 실습' 카테고리의 다른 글
167. [AI][Android Studio] 로직개발하기 : 다중페이지 개발(Activity Lifecycle) (0) | 2025.03.05 |
---|---|
165. [AI][Android Studio] 로직개발하기 : 고양이 수명계산하기 (0) | 2025.03.04 |
164. [AI][Android Studio] 로직개발하기 : 주사위게임 앱 제작 (1) | 2025.03.03 |
163. [AI][Android Studio] Android Activity Lifecycle(활동 수명 주기) 완벽 가이드 (0) | 2025.03.03 |
162. [AI][Android Studio] 안드로이드 스튜디오 설치하는 방법 (0) | 2025.03.03 |