Progress Indicator using Jetpack Compose
What is a progress indicator?
A progress indicator is an indicator to indicate the user that action is in progress and they will get the required result soon. Suppose that something is loading in our app in that case while loading we can show some logo, animation or something to enhance the user experience by providing visual feedback during long-running tasks or processes, reducing perceived wait times and keeping users engaged.
Jetpack Compose provides two types of indicators Linear Progress Indicator and Circular Progress Indicator.
1. Linear Progress Indicator - Linear Progress Indicator showing a bar horizontally on the screen that fills from left to right way.
2. Circular Progress Indicator - Circular Progress Indicator is in circular shape showing progress.
Click to create a game using jetpack compose?
When should we use progress indicator?
We should use progress indicator in the following cases
- Loading Data: When data is being loaded from the network or a database.
- Uploading/Downloading: During file uploads or downloads.
- Processing: While processing data or executing lengthy computations.
- Installation/Updates: When installing or updating software or packages.
What is benefit of using progress indicator in our app?
Following are the reasons for using Progress Indicators
1. Communicate Progress:
Feedback:
They provide feedback that a task is ongoing, reassuring users that the app is responsive and their action is being processed.
Completion:
Indicate how much of the task has been completed, which helps users estimate the remaining time or effort.
2. Improve User Experience:
Reduce Uncertainty:
They reduce uncertainty by visually conveying that the app is working on a task. This helps prevent users from becoming frustrated or assuming the app has frozen or crashed.
Perceived Speed:
Showing progress can make operations seem faster, even if the actual time taken is unchanged. This is known as reducing perceived latency.
3. Enhance Usability:
Prevent Repeated Actions:
By showing that a task is in progress, they prevent users from repeating actions unnecessarily (e.g., clicking a button multiple times).
Visual Engagement:
They provide a point of focus, engaging users visually and keeping them informed during waits.
4. Aesthetic and Consistency:
Visual Appeal: They contribute to the overall design and aesthetic of the application, making it look polished and professional.
Consistent UX: Consistent use of progress indicators across an app ensures a unified user experience and helps users understand what to expect.
How to use Progress indicator in Android App?
A simple Linear Progress Indicator
var currentProgress by remember { mutableFloatStateOf(0f) }
LinearProgressIndicator(
progress = { currentProgress },
modifier = Modifier.fillMaxWidth(),
)
A simple Circular Progress Indicator
var currentProgress by remember { mutableFloatStateOf(0f) }
CircularProgressIndicator(progress = { currentProgress })
Let's create a New Project
MainActivity
Copy this code →
package com.example.myfirstapp
import ...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyFirstAppTheme {
ProgressIndicatorExample()
}
}
}
}
ComposeProgressIndicator
Copy this code →
package com.example.myfirstapp
import ...
@Composable
fun ProgressIndicatorExample() {
var currentProgress by remember { mutableFloatStateOf(0f) }
var loading by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope() // Create a coroutine scope
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
.padding(60.dp)
) {
Button(onClick = {
loading = true
scope.launch {
loadProgress { progress ->
currentProgress = progress
}
loading = false // Reset loading when the coroutine finishes
}
}, enabled = !loading) {
Text("Start loading")
}
if (loading) {
LinearProgressIndicator(
progress = { currentProgress },
modifier = Modifier.fillMaxWidth(),
)
CircularProgressIndicator(progress = { currentProgress })
}
}
}
/** Iterate the progress value */
suspend fun loadProgress(updateProgress: (Float) -> Unit) {
for (i in 1..100) {
updateProgress(i.toFloat() / 100)
delay(100)
}
}
OUTPUT:
******
![Sandeep Gupta](http://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik2MuJw6Nf2-H9oGwPbg9a1QMtCY8PfIaaqNzq0234pnt65zt6Hary1M9RhmPv54pxWQarfRKzCfvrLFMXcH-tToe0LJHW8VCbi28zIjF4w-LifXw7BdSzNCII5QyqNyFAF2fjPn-VJej9q6e0xG1_rbeireNQegXwm21kLDDvaKqy8A/w130/author%20(1).png)