Android Studio/base_Project

[기본] 갤럭시 스톱워치 클론코딩 (2/3 기능구현)

내손은개발 🐾 2024. 2. 7. 20:45

먼저 뷰바인딩은 해주고 시작

더보기

viewBinding{
    enable = true
}

 

기능 구현 시작!

 

1. Button 

먼저 버튼 보여지는 방식을 단순하게 만들었다.

        binding.startButton.setOnClickListener{ // 구간기록, 중지
            start()
            binding.startButton.isVisible = false
            binding.continueButton.isVisible = false
            binding.pauseButton.isVisible = true
            binding.clearButton.isVisible = false
            binding.lapButton.isVisible = true
        }

시작 버튼을 누르면 구간기록과 중지 버튼이 보이도록 isVisible을 사용하였다.

나머지도 똑같이 만들어 주면 된다.

 

2. 시간작업

    private fun start() {
        timer(initialDelay = 0, period = 100) {
            currentDeciSecond += 1


            val minutes = currentDeciSecond.div(10) / 60
            val seconds = currentDeciSecond.div(10) % 60
            val deciSeconds = currentDeciSecond % 10

            runOnUiThread {
                binding.timeTextView.text =
                    String.format("%02d:%02d", minutes, seconds)
                binding.tickTextView.text = deciSeconds.toString()
            }

        }
    }

 

2-1) timer

더보기

public inline fun timer(name: String? = null, daemon: Boolean = false, initialDelay: Long = 0.toLong(), period: Long, crossinline action: TimerTask.() -> Unit): Timer {
val timer = timer(name, daemon)
timer.schedule(initialDelay, period, action)
return timer
}

간단하게 보면 initialDelay와 period를 필수 값으로 넣어줘야한다.

initialDelay는 얼마나 멈췄다가 실행

period는 어떤 주기로 수행하겠는지.

 

2-2) ThreadException 발생 !!

쓰레드는 Main에서만 UI작업이 가능하다

	runOnUiThread {
		binding.timeTextView.text =
        	String.format("%02d:%02d", minutes, seconds)
		binding.tickTextView.text = deciSeconds.toString()
	}

runOnUiThread를 꼭 사용하자

 

2-3) 일시정지 / 초기화

    private fun continueBtn() {  //2
        start()
    }

    private fun pause() {  //1
        timer?.cancel()
        timerMilli?.cancel()
        timer = null
        timerMilli = null
    }

    private fun clear() { //3
        currentDeciSecond = 0
        time = 0

        binding.timeTextView.text = "00:00."
        binding.tickTextView.text = "00"
        binding.lapContainerLinearLayout.removeAllViews()
    }

간단해서 설명 생략

 

3. 기록 저장

DB를 사용하는 것도 아니고 그냥 그 순간을 저장한다라기보다는 그 순간의 시간을 Text에 띄운다는 식이여서

간단히 해결하였다.

    private fun lap() {
        var container = binding.lapContainerLinearLayout
        TextView(this).apply {
            textSize = 20f
            gravity = Gravity.CENTER
            var minutes = currentDeciSecond.div(10) / 60
            var seconds = currentDeciSecond.div(10) % 60
            var milliSecond = time % 100

            text = container.childCount.inc().toString() + String.format(
                ".  %02d:%02d.%02d", minutes, seconds, milliSecond
            )
            setPadding(30)
        }.let {lapTextView ->
            container.addView(lapTextView,0)
        }
    }

 

이렇게하면 기존 갤럭시 휴대폰에 있는 타이머와 똑같.. 비슷하다!

애니메이션은 제외


 

구현 안된점

 

1. 갤럭시의 기록 저장을 누르면 2가지 기록이 저장된다.

  • 구간기록
    • 구간 기록을 누르는 순간마다(전 기록)부터 기록이 저장된다.
  • 전체시간
    • 구현한 구간 기록 그 자체

2. 1에서 말한 구간기록 버튼이 눌릴때마다 시작한 시간 밑에 새로운 시간이 리셋된다.

 - 구지 구현하기보단 다른 프로젝트를 구현하고 싶어 생략했다.(처음 분석에서 발견 못한점이기도 하다..)


결과

 

비교하기 쉽게 기존 갤럭시의 스톱워치와 내가 클론코딩한 스톱워치를 준비했다.

기존 갤럭시의 스톱워치 나의 클론 코딩

 

 

 

 

 

 

 

 

최종코드는 깃헙에 올리겠습니다