Wed. Jan 15th, 2025

To create a horizontal progress dialog in Jetpack Compose, you can use a combination of a Dialog and LinearProgressIndicator. This approach allows you to display either an indeterminate or a determinate horizontal progress bar.


Example: Indeterminate Horizontal Progress Dialog

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

@Composable
fun HorizontalProgressDialogExample() {
    val showDialog = remember { mutableStateOf(false) }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = { showDialog.value = true }) {
            Text("Show Horizontal Progress Dialog")
        }

        if (showDialog.value) {
            HorizontalProgressDialog(
                message = "Loading, please wait...",
                onDismiss = { showDialog.value = false }
            )
        }
    }
}

@Composable
fun HorizontalProgressDialog(message: String, onDismiss: () -> Unit) {
    Dialog(onDismissRequest = onDismiss) {
        Box(
            modifier = Modifier
                .fillMaxWidth(0.8f)
                .background(Color.White, shape = RoundedCornerShape(16.dp))
                .padding(16.dp),
            contentAlignment = Alignment.Center
        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Text(message, color = Color.Black)
                Spacer(modifier = Modifier.height(16.dp))
                LinearProgressIndicator(
                    modifier = Modifier.fillMaxWidth(),
                    color = Color.Blue
                )
            }
        }
    }
}

Example: Determinate Horizontal Progress Dialog

For a determinate progress bar, you need to manage the progress state:

import androidx.compose.runtime.*

@Composable
fun DeterminateHorizontalProgressDialogExample() {
    val showDialog = remember { mutableStateOf(false) }
    val progress = remember { mutableStateOf(0.0f) }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = { showDialog.value = true }) {
            Text("Show Determinate Progress Dialog")
        }

        if (showDialog.value) {
            DeterminateHorizontalProgressDialog(
                progress = progress.value,
                message = "Uploading...",
                onDismiss = { showDialog.value = false }
            )

            // Simulate progress updates
            LaunchedEffect(Unit) {
                while (progress.value < 1.0f) {
                    progress.value += 0.1f
                    kotlinx.coroutines.delay(500) // Simulate a delay
                }
            }
        }
    }
}

@Composable
fun DeterminateHorizontalProgressDialog(progress: Float, message: String, onDismiss: () -> Unit) {
    Dialog(onDismissRequest = onDismiss) {
        Box(
            modifier = Modifier
                .fillMaxWidth(0.8f)
                .background(Color.White, shape = RoundedCornerShape(16.dp))
                .padding(16.dp),
            contentAlignment = Alignment.Center
        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Text(message, color = Color.Black)
                Spacer(modifier = Modifier.height(16.dp))
                LinearProgressIndicator(
                    progress = progress,
                    modifier = Modifier.fillMaxWidth(),
                    color = Color.Green
                )
            }
        }
    }
}

Explanation

  1. Indeterminate Progress:
  • Use LinearProgressIndicator() without a progress parameter to show an indeterminate horizontal loader.
  1. Determinate Progress:
  • Provide a progress value (between 0.0f and 1.0f) to LinearProgressIndicator for determinate loading.
  1. State Management:
  • Manage dialog visibility and progress updates using remember or external state.
  1. Customization:
  • Adjust colors, padding, and shape for a polished look.

Optional Enhancements

  1. Custom Colors:
  • Use the color and backgroundColor parameters of LinearProgressIndicator for styling.
  1. Animations:
  • Smoothly animate progress changes using the animateFloatAsState API.
   val animatedProgress by animateFloatAsState(targetValue = progress.value)
  1. Cancelable Behavior:
  • Ensure the Dialog can be dismissed via onDismissRequest for better UX.

This approach allows for a clean and flexible implementation of horizontal progress dialogs in Jetpack Compose.

By Rajashekar

I’m (Rajashekar) a core Android developer with complimenting skills as a web developer from India. I cherish taking up complex problems and turning them into beautiful interfaces. My love for decrypting the logic and structure of coding keeps me pushing towards writing elegant and proficient code, whether it is Android, PHP, Flutter or any other platforms. You would find me involved in cuisines, reading, travelling during my leisure hours.

Leave a Reply

Your email address will not be published. Required fields are marked *