0

I'm trying to implement simple countdown timer inside fragment (without view model or use case). Here is my code:

private fun startTimer(totalSeconds: Int): Flow<Int> =
    (totalSeconds - 1 downTo 0)
        .asFlow() 
        .onEach { delay(1000) } 
        .onStart { emit(totalSeconds) } 
        .conflate() 
        .transform { remainingSeconds: Int ->
            emit(remainingSeconds)
        }

And inside onCreate(savedInstanceState: Bundle?):

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        TestTimerTheme {
            val scope = rememberCoroutineScope()
            lifecycleScope.launchWhenResumed {
                scope.launch {
                    startTimer(60)
                        .collect {
                            Log.d("MY_TAG", "sec = $it") // THIS is called many times for second
                            mutableState.emit(it)
                        }
                }
            }
            val state = mutableState.collectAsState()
            CustomTimer(state.value)
        }
    }
}

As a result, the flow randomly emits values. That is, not one event per second is emitted, but several. Please tell me what needs to be fixed in my code so that the timer works fine and gives out values only once a second.

testivanivan
  • 967
  • 13
  • 36

1 Answers1

0

Please try the following timer function:

fun startTimer(totalSeconds: Int): Flow<Int> = flow {
    var seconds = totalSeconds
    do {
        emit(seconds)
        delay(1000)
        seconds -= 1
    } while (seconds >= 0)
}
Sergio
  • 27,326
  • 8
  • 128
  • 149