jetpack compose - Count down flow

This code demonstrates a countdown timer implemented using Jetpack Compose and Kotlin Flow. It utilizes a ViewModel to manage the countdown logic and exposes the current count as a flow that can be collected and displayed in the UI.

Code Breakdown:

  1. MainActivity:

    • This is the main activity class that sets up the UI using Jetpack Compose.
    • It defines the setContent block with a Scaffold composable for the app layout.
    • The MainContent composable is used for displaying the countdown timer.
  2. MainContent:

    • It retrieves the MyViewModel instance using viewModel composable.
    • It collects the countDownFlow from the ViewModel using collectAsState. This converts the flow into a composable state variable (counter) with an initial value of 20.
    • It displays the current countdown value using a Text composable with the value from counter.
  3. MyViewModel:

    • This ViewModel class holds the logic for the countdown timer.
    • It defines a countDownFlow as a flow of integers.
    • This flow starts with a startingNumber (20) and uses a while loop to decrement the currentNumber by 1 every second using delay(1000).
    • Inside the loop, the flow emits the updated currentNumber using emit.
  4. build.gradle:

    • This snippet shows the relevant dependencies for using ViewModel and ViewModel Compose with Jetpack Compose.

Summary

This code provides a basic example of building a countdown timer in Jetpack Compose. The separation of concerns with ViewModel and the use of Flow allows for a clear and manageable implementation. It demonstrates how to collect and display data from a flow within a composable function.


MainActivity.kt

package com.cfsuman.composestate

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import com.cfsuman.composestate.ui.theme.ComposeStateTheme


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeStateTheme {
                Scaffold(
                    topBar = { TopAppBar(
                        title = {
                            Text(text = "Compose - Count down flow")
                        }
                    )},
                    content = { MainContent() },
                    backgroundColor = Color(0xFFEDEAE0)
                )
            }
        }
    }
}


@Composable
fun MainContent() {
    val viewModel = viewModel<MyViewModel>()
    val counter = viewModel.countDownFlow
        .collectAsState(initial = 20)

    Box(
        Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "${counter.value}", fontSize = 40.sp)
    }
}
MyViewModel.kt

package com.cfsuman.composestate

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow

class MyViewModel:ViewModel() {
    val countDownFlow = flow<Int> {
        val startingNumber = 20
        var currentNumber = startingNumber
        while (currentNumber > 0){
            delay(1000)
            currentNumber--
            emit(currentNumber)
        }
    }
}
build.gradle [app]

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-alpha06"
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha06"
}
More android jetpack compose tutorials