Jetpack compose: How to use kotlin flow

Introduction

This code demonstrates how to utilize Kotlin flows within a Jetpack Compose application. It showcases a scenario where the UI element's color changes periodically. Kotlin flows provide a powerful mechanism for managing asynchronous data streams in Jetpack Compose, making them ideal for handling UI updates based on changing data.

Breakdown

The code is divided into two main parts:

  • MainActivity: This class serves as the entry point for the application. It sets up the content of the activity using Jetpack Compose. The setContent function defines the composable hierarchy that represents the UI.

  • MainContent: This composable function builds the actual UI content. Here's a step-by-step breakdown:

    • Color Flow: A flow is created using the flow builder function. This flow randomly generates a new Color object every second (1000 milliseconds) using delay and emit.
    • Collecting the Flow: Inside MainContent, colorFlow.collectAsState(initial = Color.Yellow) is used. This function collects the values emitted by the colorFlow and converts them into a composable state variable named color. The initial value of color is set to Color.Yellow before any emissions occur from the flow.
    • Building the UI: A Box with fillMaxSize modifier fills the entire screen. This Box contains another centered Box with a circular clip (CircleShape) and a background color set to the current value of color. This ensures the entire circular element changes color whenever a new value is emitted by the flow.

Summary

This code effectively demonstrates how to leverage Kotlin flows for dynamic UI updates in Jetpack Compose. The flow continuously generates random colors, and the collectAsState function ensures the composable UI element reflects these changes by updating its background color accordingly. This approach allows for a reactive and data-driven UI experience.


MainActivity.kt

package com.cfsuman.composestate

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.cfsuman.composestate.ui.theme.ComposeStateTheme
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlin.random.Random


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


@Composable
fun MainContent() {
    val colorFlow = flow<Color> {
        val color = Color(
            Random.nextInt(256),
            Random.nextInt(256),
            Random.nextInt(256)
        )
        delay(1000)
        emit(color)
    }

    val color by colorFlow.collectAsState(initial = Color.Yellow)
    Box(
        Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Box(
            Modifier
                .size(250.dp)
                .clip(CircleShape)
                .background(color)
        )
    }
}
More android jetpack compose tutorials