안드로이드 코틀린

[Kotlin][Android] 안드로이드 코루틴(Coroutine) 으로 타이머 기능 만들기

teamnova 2022. 4. 25. 12:00
728x90

첫번쨰로 해야할것은 gradle 에 3가지를 추가해줘야합니다.

해당 예제는 코루틴, ViewModel, LiveData를 사용하기 떄문에 아래와 같이 해줍니다.

    // 코루틴
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"

 

두번쨰로는 VIewModel 을 아래와 같이 작성해줍니다.

class MainViewModel : ViewModel() {

    // Set
    private val _timerCount = MutableLiveData<Int>()

    // Get
    val timerCount : LiveData<Int>
        get() = _timerCount

    private lateinit var a : Job


    init{

        // viewModel 생성시 시간초 초기화
        _timerCount.value = 10

    }

    // 타이머 진행
    fun timerStart(){

        if(::a.isInitialized) a.cancel()
        _timerCount.value = 10
        a = viewModelScope.launch {
            while(_timerCount.value!! > 0) {
                _timerCount.value = _timerCount.value!!.minus(1)
                delay(1000L)
            }
        }

    }

    // 타이머 중지
    fun timerStop(){
        if(::a.isInitialized) a.cancel()
    }
}

 

그후 activity_main.xml 에 데이터 바인딩을 준비를 해줍니다.

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
        <variable
            name="viewModel"
            type="com.androd.corutine_example.MainViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="Activity/Fragment">

        <TextView
            android:id="@+id/timer_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Integer.toString(viewModel.timerCount)}"
            app:layout_constraintBottom_toBottomOf="parent"
            android:textSize="30sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.226" />

        <Button
            android:id="@+id/startButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="36dp"
            android:text="시작"
            android:textSize="19sp"
            android:onClick="@{() -> viewModel.timerStart()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/timer_view" />

        <Button
            android:id="@+id/pauseButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:text="정지"
            android:textSize="19sp"
            android:onClick="@{() -> viewModel.timerStop()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/startButton" />
        

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

그리고 나서 MainActivity에 데이터 바인딩을 연결시켜주고, 

ViewModelProvider를 통해서 ViewModel 을 생성해줍니다.

 

class MainActivity : AppCompatActivity() {

    lateinit var mainViewModel: MainViewModel
    lateinit var binding : ActivityMainBinding



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)

        mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        binding.viewModel = mainViewModel

        binding.lifecycleOwner = this
        setContentView(binding.root)

    }
}