본문 바로가기
Android

[Android] Chronometer를 이용해 스탑워치 만들기

by jane.dev 2021. 10. 24.
반응형

activity_main.xml

먼저 LinearLayout 내부에 Chronometer 생성

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center|top">
    
    <Chronometer
        android:id="@+id/cm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:format="시간 측정: %s"
        android:gravity="center"
        android:textSize="30dp" />
        
</LinearLayout>

format의 %s는 MM:SS 형식으로 출력됨

 

<!-- 타이머 시작 버튼 -->
<Button
    android:id="@+id/start"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="start"></Button>
<!-- 타이머 정지 버튼 -->
<Button
    android:id="@+id/stop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="stop"></Button>
<!-- 타이머 초기화 버튼 -->
<Button
    android:id="@+id/reset"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="reset"></Button>

Chronometer아래 Button을 세개 나열해 타이머가 시작하고 정지하고 리셋될 수 있도록 함

 

MainActivity.java

public class MainActivity extends AppCompatActivity {
    
    
    Chronometer cm;
    Button start, stop, reset;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        
        cm = (Chronometer)findViewById(R.id.cm);
        start = (Button)findViewById(R.id.start);
        stop = (Button)findViewById(R.id.stop);
        reset = (Button)findViewById(R.id.reset);
        
        // 시작버튼 click event
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cm.start();
            }
        });
        // 정지버튼 click event
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cm.stop();
            }
        });
        // 초기화버튼 click event
        reset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cm.setBase(SystemClock.elapsedRealtime());
                cm.stop();
            }
        });
    }
}

start() 는 카운트 업을 시작함

stop() 는 카운트 업을 중지시키며, start()에서 리소스 누수가 발생하지 않도록 상호호출이 있는지 확인해야함

setBase()는 카운트 업 타이머가 참조되는 시간을 설정하는 것이고, 파라미터에 SystemClock.elapsedRealtime() 타임 베이스를 사용

SystemClock.elapsedRealtime()는 디바이스가 부팅된 이후부터의 시간을 절전모드를 포함해 가져오는 것인데 어떠한 원리로 reset이 되는지 모르겠다...

 

→ 이렇게 작성하면 문제가 있음

 

start 버튼 클릭 

- stop 버튼 클릭 

- 다시 start 버튼을 누를 때, 멈춘 시간부터 타이머가 시작되어야 하는데, 멈춘시간이 포함된 시간부터 타이머가 시작됨

 

public class MainActivity extends AppCompatActivity {

    Chronometer cm;
    Button start, stop, reset;

    // 정지버튼이 눌리고 시간이 흐르고 있는 것을 감지하는 변수
    boolean running;
    // 정지한 시간을 재는 변수
    long pause;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        cm = (Chronometer)findViewById(R.id.cm);
        start = (Button)findViewById(R.id.start);
        stop = (Button)findViewById(R.id.stop);
        reset = (Button)findViewById(R.id.reset);

        // 시작버튼
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(!running){
                    // 현재 나타내려는 시간을 디바이스 부팅시간부터 정지버튼이 눌린시간인 pause을 빼줌
                    cm.setBase(SystemClock.elapsedRealtime() - pause);
                    // 타이머가 다시 시작
                    cm.start();
                    running = true;
                }

            }
        });
        // 정지버튼
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 여기서부터 시작, 정지버튼이 눌리면 running은 true
                if(running){
                    // 타이머 정지
                    cm.stop();
                    // 정지한 시간은 디바이스가 부팅된 시간에서 현재 표시되어 있는 시간을 빼줌
                    pause = SystemClock.elapsedRealtime() - cm.getBase();
                    running = false;
                }

            }
        });
        // 초기화버튼
        reset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cm.setBase(SystemClock.elapsedRealtime());
                cm.stop();
                /* 시작버튼이 다시눌리면 0부터 시작되기 때문에 
                 * 정지한 시간을 0으로 만들어 시간이 -가 되지 않도록함
                 */
                pause = 0;
            }
        });
    }
}