전체 코드 : https://github.com/ryr0121/AndroidPractice/tree/main/stopwatchApp
구현 결과
주요 기능
- 카운트다운
- 스톱워치 (시작/일시정지/정지)
- 중간 기록 추가
ConstraintLayout으로 view 배치
Dialog / ProgressBar 를 통한 카운트다운 설정 및 현황 파악
// AlertDialog를 이용한 카운트다운 설정창 열기
private fun showCountdownSettingDialog() {
AlertDialog.Builder(this).apply {
val dialogBinding = DialogCountdownSettingBinding.inflate(layoutInflater)
with(dialogBinding.countdownSecondPicker) {
maxValue = 20
minValue = 0
value = countdownSecond
}
setView(dialogBinding.root)
setTitle("카운트다운 설정")
setPositiveButton("확인") { _, _ ->
countdownSecond = dialogBinding.countdownSecondPicker.value
currentCountdownDeciSecond = countdownSecond * 10
binding.countdownTextView.text = String.format("%02d", countdownSecond)
}
setNegativeButton("취소",null)
}.show()
}
// ProgressBar 추가
<ProgressBar
android:id="@+id/countdownProgressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
app:layout_constraintBottom_toTopOf="@id/timeTextView"
app:layout_constraintStart_toStartOf="parent" />
// ProgressBar 설정
private fun start() {
timer = timer(initialDelay = 0, period = 100) {
if (currentCountdownDeciSecond == 0) {
...
} else {
currentCountdownDeciSecond -= 1
val sec = currentCountdownDeciSecond/10
val progress = (currentCountdownDeciSecond/(countdownSecond * 10f)) * 100
binding.root.post {
...
binding.countdownProgressBar.progress = progress.toInt()
}
}
...
}
}
ScrollView와 LinearLayout을 활용한 시간 기록 view 구성
<ScrollView
android:id="@+id/lapScrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="50dp"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline">
<LinearLayout
android:id="@+id/lapContainerLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
코드를 활용한 시간 기록 TextView 생성 및 ScrollView에 추가
private fun lap() {
if (currentDeciSecond == 0) return
val container = binding.lapContainerLinearLayout
TextView(this).apply {
textSize = 20f
gravity = Gravity.CENTER
val min = currentDeciSecond.div(10)/60
val sec = currentDeciSecond.div(10)%60
val deciSec = currentDeciSecond%10
text = "${container.childCount.inc().toString()}. " + String.format(
"%02d:%02d:%02d",
min,
sec,
deciSec
)
setPadding(30)
}.let { lapTextView ->
container.addView(lapTextView, 0)
}
}
workThread와 runOnUiThread / post 메소드를 이용한 UI 작업 비동기 처리
private fun start() {
timer = timer(initialDelay = 0, period = 100) {
if (currentCountdownDeciSecond == 0) {
// UI 업데이트가 아닌 다른 작업의 비동기 처리
currentDeciSecond += 1
val min = currentDeciSecond.div(10)/60
val sec = currentDeciSecond.div(10)%60
val deciSec = currentDeciSecond%10
// runOnUiThread를 활용한 UI 업데이트 작업 진행
runOnUiThread {
binding.timeTextView.text = String.format("%02d:%02d", min, sec)
binding.tickTextView.text = deciSec.toString()
binding.countdownGroup.isVisible = false
}
} else {
// UI 업데이트가 아닌 다른 작업의 비동기 처리
currentCountdownDeciSecond -= 1
val sec = currentCountdownDeciSecond/10
val progress = (currentCountdownDeciSecond/(countdownSecond * 10f)) * 100
// post 메소드를 활용한 UI 업데이트 작업 진행
binding.root.post {
binding.countdownTextView.text = String.format("%02d", sec)
binding.countdownProgressBar.progress = progress.toInt()
}
}
...
}
}
ToneGenerator를 활용한 알림음 추가
val toneType = if(currentCountdownDeciSecond == 0) ToneGenerator.TONE_CDMA_HIGH_L else ToneGenerator.TONE_CDMA_ANSWER
ToneGenerator(AudioManager.STREAM_ALARM, ToneGenerator.MAX_VOLUME)
.startTone(toneType, 100)
'Android' 카테고리의 다른 글
[Android] "계산기 앱" 구현 (0) | 2024.06.30 |
---|---|
[Android] "응급 의료정보 앱" 구현 (0) | 2024.06.30 |
[Android] "단위 변환기 앱" 구현 (4) | 2024.06.26 |
[Android] "숫자세기 앱" 구현 (7) | 2024.06.25 |