
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.

There are two types of linear progress indicators – indeterminate and determinate.
1. Indeterminate Linear Progress Indicator:
It runs forever.

2. Determinate Linear Progress Indicator:
It shows a progress value.

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:

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:

Stroke Cap:
We can change the edge of the indicator using the strokeCap parameter. There are three values:
- Butt (default)
- Round
- 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:

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:

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:

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:

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: