Linear Progress Indicator in Material 3 Jetpack Compose

Jetpack Compose Material 3 Linear Progress Indicator

In this article, we’ll learn how to implement the linear progress indicator in Material 3 Jetpack Compose.

Prerequisites:

What is a Linear Progress Indicator?

It shows the status of a process along a line. We use it when loading an app, submitting a form, or saving updates.

Linear Progress Indicator

There are two types of linear progress indicators – indeterminate and determinate.

1. Indeterminate Linear Progress Indicator:

It runs forever.

Indeterminate Linear Progress Indicator

2. Determinate Linear Progress Indicator:

It shows a progress value.

Determinate Linear Progress Indicator

Let’s see how to implement them in the Android Studio.

First, create an empty Compose project and open MainActivity. Create a MyUI() composable and call it from the onCreate() method. We’ll write our code in it.

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {

}

1. Indeterminate Linear Progress Indicator:

The API looks like this:

@Composable
fun LinearProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.linearColor,
    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap,
)

modifier – The Modifier to be applied to this progress bar.

color – Foreground color of the indicator.

trackColor – Background color of the indicator.

strokeCap – Stroke cap of this progress bar.

Example:

@Composable
fun MyUI() {
    LinearProgressIndicator(
        modifier = Modifier.width(width = 200.dp),
        color = Color.Green
    )
}

Output:

Indeterminate Linear Progress Indicator

Indicator Height:

We can change the indicator’s height using the size modifiers like height(), width(), size(), etc.

@Composable
fun MyUI() {
    LinearProgressIndicator(
        modifier = Modifier.size(width = 200.dp, height = 8.dp),
        color = Color.Green
    )
}

Output:

Indicator Height

Stroke Cap:

We can change the edge of the indicator using the strokeCap parameter. There are three values:

  1. Butt (default)
  2. Round
  3. Square

Let’s set the Round cap.

@Composable
fun MyUI() {
    LinearProgressIndicator(
        modifier = Modifier.size(width = 200.dp, height = 8.dp),
        color = Color.Green,
        strokeCap = StrokeCap.Round
    )
}

Output:

Stroke Cap Round

Indicator with Text:

To add the text, put the progress indicator and Text() in a Column() layout.

@Composable
fun MyUI() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LinearProgressIndicator(
            modifier = Modifier.size(width = 200.dp, height = 8.dp),
            color = Color.Green,
            strokeCap = StrokeCap.Round
        )
        Spacer(modifier = Modifier.height(height = 8.dp))
        Text(text = "Loading...")
    }
}

Output:

Indicator with Text

Related: 5 Simple Text Animations in Jetpack Compose

2. Determinate Linear Progress Indicator:

@Composable
fun LinearProgressIndicator(
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.linearColor,
    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap,
)

The progress value ranges from 0f to 1f. 0f represents no progress, and 1f means 100% progress.

Example:

@Composable
fun MyUI() {
    LinearProgressIndicator(
        progress = 0.6f,
        modifier = Modifier.size(width = 200.dp, height = 8.dp),
        color = Color.Green,
        strokeCap = StrokeCap.Round
    )
}

Output:

Determinate Linear Progress Indicator

Adding Animation:

By default, you don’t see any animation while showing the progress. We can add a smooth animation by using animateFloatAsState API.

@Composable
fun MyUI() {
    // progress value
    var progress by remember {
        mutableFloatStateOf(0f) //  or use mutableStateOf(0f)
    }

    // animation
    val progressAnimate by animateFloatAsState(
        targetValue = progress,
        animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
    )

    // this is called when the activity is launched first time
    LaunchedEffect(Unit) {
        progress = 0.6f
    }

    LinearProgressIndicator(
        progress = progressAnimate,
        modifier = Modifier.size(width = 200.dp, height = 8.dp),
        color = Color.Green,
        strokeCap = StrokeCap.Round
    )

    Spacer(modifier = Modifier.height(height = 8.dp))

    Button(
        onClick = {
            progress = (0 until 100).random().toFloat() / 100
        }
    ) {
        Text(text = "Random Value")
    }
}

Output:

Adding Animation

Note: Instead of ProgressAnimationSpec, you can specify other animation spec functions.

This is all about the Linear Progress Indicator in Material 3 Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Related Posts:


References:

Leave a Comment