상세 컨텐츠

본문 제목

안드로이드 크로노미터로 스톱워치(타이머) 쉽게 구현하기

안드로이드/코틀린, 자바

by 개발익선 2021. 1. 13. 09:15

본문

간단한 타이머(스톱워치)를 구현해보자.

 

Thread를 돌려서 구현하는 방법도 있지만, 이번 포스팅에서는

더 간단하게 크로노미터로 구현할 수 있는 방법을 알아보고자 한다.

 

단, 크로노미터(Chronometer) 기능을 활용하면 초까지만 실시간으로 보여줄 수 있고,

밀리초 단위는 elapsedRealtime을 통해 마킹(기록) 만 할 수 있다.

따라서 밀리초까지의 실시간 스톱워치는 다음 시간 스레드 방법을 통해 알아보자.

 

(코틀린, 자바를 같이 포스팅 할 수 있는 방법을 어설프게나마 터득하였다.

앞으로 쭈욱 적용!)

 

1. xml을 만들자

 

activity_test.xml을 생성하고, LinearLayout 으로 설정해 주었다.

 

Chronometer를 도구상자에서 검색 해보니

;; 왜 검색이 안되는지 모르겠다. 이미 Ch부터 안 보이는 중..

 

그래서 activity_test.xml 레이아웃 안에 직접 소스로 넣어 주었다.

아래 코드 참조 (Chronometer)

1
2
3
4
5
6
7
<Chronometer
        android:id="@+id/timer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:format="%s"
        android:textSize="20sp"/>
cs

 

 

2. 액티비티(자바 or 코틀린)를 만들자.

 

TestActivity Class를 만들어주고 소스를 넣어보자.

 

1
2
3
4
5
6
7
8
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
 
        val calculator = findViewById<View>(R.id.timer) as Chronometer
        calculator.base = SystemClock.elapsedRealtime()
        calculator.start()
    }
cs
1
2
3
4
5
6
7
8
9
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Chronometer calculator = (Chronometer) findViewById(R.id.timer);
        calculator.setBase(SystemClock.elapsedRealtime());
        calculator.start();
    }
cs

 

지금은 activity가 시작되면 자동으로 시작 하게 되어있다.

 

상황에 따라 버튼에 calculator.start() 를 넣어줄 수도 있고,

정지를 원하는 경우 calculator.stop()을 넣어주면 된다.

 

 

 

 

** 크로노미터에서 추가적으로 밀리초까지 마킹하고 싶은 경우 밀리초를 구하는 방법이다.

(앞에서 말했듯이 크로노미터 기능에서 밀리초까지 스톱워치 표현은 되지 않는다.)

TextView에서 확인해보자. (위 xml에서 TextView만 추가하면 된다.)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Chronometer
        android:id="@+id/timer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:format="%s"
        android:textSize="20sp"/>
 
<TextView
        android:id="@+id/txtMilliTimer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:text="hh:mm:ss"/>
cs

 

activity에 밀리초와 관련된 내용을 작성하자.

TextView 내용만 작성하면 구할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
 
        val calculator = findViewById<View>(R.id.timer) as Chronometer
        calculator.base = SystemClock.elapsedRealtime()
        calculator.start()
 
        val txtMilliSec = findViewById<TextView>(R.id.txtMilliTimer)
        calculator.onChronometerTickListener = OnChronometerTickListener {
            val milliSec = SystemClock.elapsedRealtime() - calculator.base
            txtMilliSec.text = ((milliSec - milliSec / 1000 * 1000) as Int).toString()
        }
    }
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Chronometer calculator = (Chronometer) findViewById(R.id.timer);
        calculator.setBase(SystemClock.elapsedRealtime());
        calculator.start();
 
        TextView txtMilliSec = findViewById(R.id.txtMilliTimer);
        calculator.setOnChronometerTickListener(chronometer -> {
            long milliSec = SystemClock.elapsedRealtime() - calculator.getBase();
            txtMilliSec.setText(String.valueOf((int) (milliSec - ((milliSec / 1000* 1000))));
        });
    }
cs

 

현재 소스는 크로노미터 자체 틱 기능으로, 틱마다 밀리초를 계산해서 보여주고 있다.

틱 안의 내용을 복사 응용해서 '기록' 버튼을 만들면 밀리초까지 스탑워치를 할 수 있는 것이다!

 

 

참고로 크로노미터의 Tick Listener는 쉽게 초 단위로 '똑딱똑딱' 하지만,

완벽하게 초마다 틱이 일어나는 것이 아니다.

그래서 밀리초가 000이 아닌 불특정의 밀리 초로 표시되는 것이다.

 

 

포스팅을 읽고,

큰 도움이 되셨다면, 공감(♥)을 던져 주세요!

큰 힘이 되어 다음 포스팅 시에도 파이팅하겠습니다.

관련글 더보기

댓글 영역