How to create a dialog with blur background in Jetpack compose?

The Dialog component displays pop up messages or requests user input on a layer above the main app content. It is a common UI component in Android applications, often used to display information or actions that require user attention. Adding a blur effect to the background when a dialog is displayed can significantly enhance the visual aesthetics of your app, providing a modern and elegant feel.

In this blog, we’ll learn how to create a blur background for a dialog in Jetpack Compose using the provided code snippet.

Key Components in the Code

  1. enableBlur and disableBlur Functions
    These are extension functions for the View class, utilizing RenderEffect to apply or remove a blur effect:
fun View.enableBlur() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val blurEffect = android.graphics.RenderEffect.createBlurEffect(
            20f, // Blur radius for X-axis
            20f, // Blur radius for Y-axis
            android.graphics.Shader.TileMode.CLAMP
        )
        this.setRenderEffect(blurEffect)
    }
}

fun View.disableBlur() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        this.setRenderEffect(null)
    }
}

These methods leverage the RenderEffect API to dynamically apply or clear the blur effect on a view.

2. ApplyBlurEffect Composable
This composable observes the isBlurred state and applies the blur effect when required:

@Composable
fun ApplyBlurEffect(isBlurred: Boolean) {
    val localView = LocalView.current

    DisposableEffect(isBlurred) {
        if (isBlurred) {
            localView.enableBlur()
        } else {
            localView.disableBlur()
        }

        onDispose {
            localView.disableBlur()
        }
    }
}

It uses LocalView to access the current view and applies the blur effect through the previously defined functions.

3. ShowBlurDialog Composable
The main composable that toggles the blur effect when a dialog is displayed:

@Composable
fun ShowBlurDialog() {
    var showDialog by remember { mutableStateOf(false) }

    Box(
        contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text(
                text = "The content will be blur when the dialog appears on screen.",
                textAlign = TextAlign.Center,
                modifier = Modifier.padding(16.dp)
            )
            Button(onClick = { showDialog = true }) {
                Text(text = "Click to show Dialog")
            }
        }
    }

    ApplyBlurEffect(isBlurred = showDialog)

    if (showDialog) {
        Dialog(
            onDismissRequest = { showDialog = false },
            properties = DialogProperties(usePlatformDefaultWidth = false)
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp),
                contentAlignment = Alignment.Center
            ) {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text("This is a dialog with blur background", fontSize = 20.sp, color = Color.Black)
                    Spacer(modifier = Modifier.height(8.dp))
                    Button(onClick = { showDialog = false }) {
                        Text("Close")
                    }
                }
            }
        }
    }
}
  • The ApplyBlurEffect is triggered when showDialog is true.
  • The dialog UI provides a simple interaction to close and toggle the blur effect.

Complete Code

Here’s the entire code snippet for reference:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            BlogDemosTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Surface(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(innerPadding),
                        color = MaterialTheme.colorScheme.background
                    ) {
                        ShowBlurDialog()
                    }
                }
            }
        }
    }
}

Leave a Comment

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