添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

posth2071/StopWatch_Kotlin

Contribute to posth2071/StopWatch_Kotlin development by creating an account on GitHub.

github.com

timer 기본 사용방법

반복주기는 peroid 프로퍼티 로 설정, 단위는 1000분의 1초 (period = 1000, 1초)

timer(preoid = 1000){
    // 1초마다 실행할 블록
    // 백그라운드로 실행되는 부분, UI조작 X

 timer 블록 내부는 워커스레드(백그라운드) 공간이기에 runOnUiThread() 메서드를 통해 UI조작
    : 시간이 오래걸릴 수 있는 로직은 워커스레드 공간에서 처리하고 UI조작만 전달

timer(preoid = 1000){
    // 오래 걸리는 작업 수행부분
    runOnUiThread {
    	// UI 조작 로직

메서드 구현

start() 함수 - 시작

start버튼을 누르면 호출되는 메서드
타이머를 시작하고 0.01초마다 화면에 시간을 갱신하는 로직, runOnUiThread()로 화면 시간 갱신

private fun start() {
    fab_start.setImageResource(R.drawable.ic_pause_black_24dp)	// 시작버튼을 일시정지 이미지로 변경
    timerTask = kotlin.concurrent.timer(period = 10) {	// timer() 호출
	time++	// period=10, 0.01초마다 time를 1씩 증가
        val sec = time / 100	// time/100, 나눗셈의 몫 (초 부분)
        val milli = time % 100	// time%100, 나눗셈의 나머지 (밀리초 부분)
	// UI조작을 위한 메서드
        runOnUiThread {	
	    secText.text = "$sec"	// TextView 세팅
            milliText.text = "$milli"	// Textview 세팅

pause() 함수 - 일시정지

타이머를 일시정지하는 함수 (초기화 X)
현재 timerTask가 진행중인지 체크 한 뒤, 진행 중이라면 cancel() 메서드를 호출해 timer를 정지

안전한 호출(?.)을 통해 간단하게 timerTask 상태를 처리가능

private fun pause() {
    fab_start.setImageResource(R.drawable.ic_play)	// 일시정지 아이콘에서 start아이콘으로 변경
    timerTask?.cancel();	// 안전한 호출(?.)로 timerTask가 null이 아니면 cancel() 호출

lapTime() 함수 - 시간 기록

현재 timer의 시간을 기록하는 함수,
ScrollView내부에 선언한 LinearLayout(Vertical 방향)최상단으로(index 0) TextView를 추가하는 방식

기록버튼을 클릭 시 Timer가 진행 중인 상태라면 기록 저장, 아니라면 저장 X

// 기록버튼 클릭리스너 등록
btn_lab.setOnClickListener {
    if(time!=0) lapTime()	// 시간 저장변수 time이 0이라면 함수호출하지 않음

기록 저장
   : TextView를 동적으로 생성해서 LinearLayout에 추가하는 방법
     apply() 함수로 TextView 선언과 동시에 초기화

private fun lapTime() {
    val lapTime = time		// 함수 호출 시 시간(time) 저장
    // apply() 스코프 함수로, TextView를 생성과 동시에 초기화
    val textView = TextView(this).apply {	
        setTextSize(20f)	// fontSize 20 설정
        text = "${lapTime / 100}.${lapTime % 100}"	// 출력할 시간 설정
    lap_Layout.addView(textView,0)	// layout에 추가, (View, index) 추가할 위치(0 최상단 의미)
    index++	// 추가된 View의 개수를 저장하는 index 변수

reset() 함수 - 초기화

Timer 기록을 초기화 하는 함수
time(시간), index(기록 개수), timerTask(타이머 객체), TextView(UI초기화), layout(추가된 기록View 모두 제거)

private fun reset() {
    timerTask?.cancel()	// timerTask가 null이 아니라면 cancel() 호출
    time = 0		// 시간저장 변수 초기화
    isRunning = false	// 현재 진행중인지 판별하기 위한 Boolean변수 false 세팅
    fab_start.setImageResource(R.drawable.ic_play)	// start아이콘 설정
    secText.text = "0"		// TextView 초기화
    milliText.text = "00"
    lap_Layout.removeAllViews()	// Layout에 추가한 기록View 모두 삭제
    index = 1

전체 코드 Activity

class MainActivity : AppCompatActivity() {
    private var time = 0
    private var isRunning = false
    private var timerTask: Timer? = null
    private var index :Int = 1
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        fab_start.setOnClickListener {
            isRunning = !isRunning
            if (isRunning) start() else pause()
        fab_reset.setOnClickListener {
            reset()
        btn_lab.setOnClickListener {
            if(time!=0) lapTime()
    private fun start() {
        fab_start.setImageResource(R.drawable.ic_pause_black_24dp)
        timerTask = kotlin.concurrent.timer(period = 10) {
            time++
            val sec = time / 100
            val milli = time % 100
            runOnUiThread {
                secText.text = "$sec"
                milliText.text = "$milli"
    private fun pause() {
        fab_start.setImageResource(R.drawable.ic_play)
        timerTask?.cancel();
    private fun reset() {
        timerTask?.cancel()
        time = 0
        isRunning = false
        fab_start.setImageResource(R.drawable.ic_play)
        secText.text = "0"
        milliText.text = "00"
        lap_Layout.removeAllViews()
        index = 1
    private fun lapTime() {
        val lapTime = time
        val textView = TextView(this).apply {
            setTextSize(20f)
        textView.text = "${lapTime / 100}.${lapTime % 100}"
        lap_Layout.addView(textView,0)
        index++

Layout XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/btn_lab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="랩 타임"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.89"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.96" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_start"
        android:layout_width="56dp"
        android:layout_height="wrap_content"
        android:backgroundTint="#5DB160"
        android:clickable="true"
        android:tint="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="@+id/btn_lab"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_lab"
        app:layout_constraintVertical_bias="0.0"
        app:srcCompat="@drawable/ic_play" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_reset"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="#D64D7C"
        android:clickable="true"
        android:tint="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="@+id/fab_start"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.12"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_lab"
        app:layout_constraintVertical_bias="1.0"
        app:srcCompat="@drawable/ic_refresh" />
    <TextView
        android:id="@+id/secText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:freezesText="false"
        android:text="0"
        android:textAllCaps="false"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textSize="100sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.100000024" />
    <TextView
        android:id="@+id/milliText"
        android:layout_width="91dp"
        android:layout_height="30dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="20dp"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toBottomOf="@+id/secText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toEndOf="@+id/secText" />
    <ScrollView
        android:id="@+id/scroll1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/fab_start"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/secText">
        <LinearLayout
            android:id="@+id/lap_Layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="vertical" />
    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>