김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • KMU_WINK
  • Remote저장소
  • 깃허브데스크탑
  • 원격저장소
  • GitHubDesktop
  • local저장소
  • ㄱ
  • 로컬저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[안드로이드 코드랩/아키텍처-4] LiveData를 transformations사용하여 변환하기, 안드로이드 타이머 구현하기
•App/안드로이드 with Kotlin

[안드로이드 코드랩/아키텍처-4] LiveData를 transformations사용하여 변환하기, 안드로이드 타이머 구현하기

2022. 8. 20. 08:47

<이전글>

 

[안드로이드 코드랩] 데이터바인딩(data-binding) 을통한 뷰모델(viewModel), 라이브데이터(liveData) 결합

<이전글> [안드로이드 코드랩] 생명주기와 로깅(Lifecycles and logging),Timber, Application클래스, 데이터바이딩(data Android Kotlin 기초  | 학습 과정  | Android Developers Android Kotlin 기초 Androi...

devforyou.tistory.com

<코드랩 과정5-4 : LiveData Transformations>

 

Android Kotlin 기초  |  학습 과정  |  Android Developers

Android Kotlin 기초 Android Kotlin 기초 교육 과정은 Google Developers 교육팀에서 만들었습니다. 이 교육 과정에서는 Android Kotlin 프로그래밍 개념에 관해 알아보고 다양한 앱을 빌드합니다. Android Kotlin 기

developer.android.com

<참고글>

 

Transformations로 LiveData 변형하기 · 쾌락코딩

Transformations로 LiveData 변형하기 13 Jul 2019 | libaray AAC LiveData 프로젝트 개발시 ViewModel을 사용함과 동시에 궁합이 잘 맞는 LiveData를 많이 사용한다. 그러나 Observavle을 위해 LiveData를 그 자체로만 사용

wooooooak.github.io


# 시작하며

 일단 지금껏 해오던 코드랩에서 한가지의 기능을 추가할 것이다. 단어가 더이상 없으면 EndGame이 되는 것이 아닌 제한시간이 지나면 게임이 종료되도록 기능을 수정한다. 또한 단어가 사라진다면 단어를 다시 섞어서(reset) 해서 보여준다.

 위 기능을 추가하기 위해서는 타이머를 구현해야한다. 또한 그냥 LONG의 자료형을 가지는 타이머를 00:00와 같은 형식으로 변환시켜야한다. 이 기능을 Transformations를 사용하면 손쉽게 구현할 수 있다.

 

# 타이머 만들기 ( ViewModel에 구현)

안드로이드에서 제공하는 유틸중에 CountDownTimer가 존재하기 때문에 어렵지 않게 구현 할 수 있다. 

companion object {
   // Time when the game is over
   private const val DONE = 0L
   
   // Countdown time interval
   private const val ONE_SECOND = 1000L
   
   // Total time for the game
   private const val COUNTDOWN_TIME = 60000L
}

타이머에서 사용되는 1Tick과 전체 주어진 시간을 설정하기 위한 static한 변수를 만들어준다.

남은시간또한 LiveData로 활용한다면 시간이 변화할때마다 UI를 새로 업데이트 시켜 줄 수 있을 것이다.

// Countdown time
private val _currentTime = MutableLiveData<Long>()
val currentTime: LiveData<Long>
   get() = _currentTime

 

이제 timer를 만들어줘야한다. timer는 게임이 시작됐을때 작동해야하기 때문에, init블럭 안에다가 만들어줘야 한다.

private val timer: CountDownTimer

init {
    timer = object : CountDownTimer(COUNTDOWN_TIME, ONE_SECOND){
        override fun onTick(millisUntilFinished: Long) {
            Log.d(TAG,_currentTime.value.toString())
            _currentTime.value = millisUntilFinished/ ONE_SECOND
        }
        override fun onFinish() {
            _currentTime.value = DONE
            onGameFinish()
        }
    }.start()
}

뷰모델이 종료되는 시점에는 타이머또한 메모리에서 해제해주어 메모리 누수를 막아준다.

override fun onCleared() {
   super.onCleared()
   // Cancel the timer
   timer.cancel()
}

타이머의 기능 구현을 끝냈다. 이제 카드가 더이상 존재하지 않을때 시간이 남아있다면 카드를 다시 섞어주도록 기능을 개선해준다.

private fun nextWord() {
    if (!wordList.isEmpty()) {
        //Select and remove a word from the list
        _word.value = wordList.removeAt(0)
    } else {
        // 단어가 없을때 게임이 종료될 수 있도록
        resetList()
    }

지금 시점에서 currentTime에는 LiveData가 담겨 있으며, 1초라면 1000L, 2초라면 2000L과 같은 데이터가 담겨져 있을 것이다. 우리가 화면에 표현해야하는 것은 00:01과 같은 형식이기에 라이브 데이터를 변환시켜야 한다. 

 

# Transformations 사용

Transformations.map()을 사용한다면 이러한 LiveData를 손쉽게 변환할 수 있다. 라이브데이터source를 건네받고 함수안에서 변환시킨다음에 변환된 LiveData를 반환 시킨다.

코드랩

특히 주목해야 할 것은, Transformations.map()을 사용한다면, source로 주어지는 원본 LiveData의 value가 갱신될때마다 함께 갱신된다. 참고로 적어놨던 블로그에서 MediatiorLiveData를 사용하기 때문에 가능하다고 적어주셨다.

위에 설명을 참고하며 아래와 같이 코드를 작성해주자. DateUtils를 통해서 남은시간을 손쉽게 00:00과 같은 형태로 만들어 줄 수 있고 이 것이 LiveData가 되어 반환된다.

// The String version of the current time
val currentTimeString = Transformations.map(currentTime) { time ->
   DateUtils.formatElapsedTime(time)
}

이렇게 생성된 currentTimeString을 UI에 업데이트 시켜줘야한다. 프래그먼트에서 Observer를 통해서 구현할 수 있겠지만 이번 코드랩에서는 data-binding을 사용했기 때문에 xml에 추가해주는 것만으로도 손쉽게 연결이 가능했다.

<TextView
   android:id="@+id/timer_text"
   ...
   android:text="@{gameViewModel.currentTimeString}"
   ... />

 

# 마치며

ViewModel과 LiveData에 대해서 배우게 되면서 지금껏 내가 작성했던 코드들이 매우 체계가 없었음을 깨달아 가고 있다. 

저작자표시 (새창열림)

'•App > 안드로이드 with Kotlin' 카테고리의 다른 글

[안드로이드 코드랩/Room-2] 코루틴을 이용해 Room CRUD구현해보기, LiveData를 반환하는 DAO  (0) 2022.08.21
[안드로이드 코드랩/Room-1] 안드로이드 Room-DB만들기, Entity개념, DAO  (1) 2022.08.21
[안드로이드 코드랩/아키텍처-3] 데이터바인딩(data-binding) 을통한 뷰모델(viewModel), 라이브데이터(liveData) 결합  (0) 2022.08.19
[안드로이드 코드랩/아키텍처-2] 뷰모델에서 LiveData사용하기, MutableLiveData와 LiveData 차이점, UI 한번에 변경하기  (0) 2022.08.18
[안드로이드 코드랩/아키텍처-1] 뷰모델(ViewModel) 초간단 이해 및 사용하는 이유, MVVM 아키텍처  (0) 2022.08.13
    '•App/안드로이드 with Kotlin' 카테고리의 다른 글
    • [안드로이드 코드랩/Room-2] 코루틴을 이용해 Room CRUD구현해보기, LiveData를 반환하는 DAO
    • [안드로이드 코드랩/Room-1] 안드로이드 Room-DB만들기, Entity개념, DAO
    • [안드로이드 코드랩/아키텍처-3] 데이터바인딩(data-binding) 을통한 뷰모델(viewModel), 라이브데이터(liveData) 결합
    • [안드로이드 코드랩/아키텍처-2] 뷰모델에서 LiveData사용하기, MutableLiveData와 LiveData 차이점, UI 한번에 변경하기
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바