Jetpack Compose Snackbar alternative – InfoBar Compose library

Jetpack Compose Snackbar alternative – InfoBar Compose library

As the Snackbar available in Google’s Compose Material library doesn’t offer a quick and intuitive way to display on-screen messages, requiring multiple steps like using a Scaffold or a SnackbarHost / SnackbarHostState combo and handling coroutines, the InfoBar Compose library acts as a Jetpack Compose Snackbar alternative, aiming to provide a quicker way to display Snackbar-style on-screen messages. Moreover, it offers multiple customization options through dedicated parameters.

How easy can it be?

Firstly, include the library in your module-level build.gradle file:

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.radusalagean:info-bar-compose:1.0.0'
}

Afterwards, Display a simple message at the press of a button:

setContent {
    YourAppTheme {
        Box(Modifier.fillMaxSize().padding(16.dp)) {
            var message: InfoBarMessage? by remember { mutableStateOf(null) }
            Button(
                modifier = Modifier.align(Alignment.Center),
                onClick = { message = InfoBarMessage(text = "Example message") }
            ) {
                Text("Show message")
            }
            InfoBar(offeredMessage = message) {
                message = null
            }
        }
    }
}
InfoBar Compose - The Jetpack Compose Snackbar alternative

Let’s take this example and explain it step by step:

  1. Create a mutable state holder called message, which is of nullable type InfoBarMessage, and remember { ... } it, since we declare it inside a composable, initializing it to null;
  2. Assign the message to an InfoBarMessage instance, describing the message you want to be displayed on the screen. There are multiple parameters available, ranging from text to action (if you want to have an interactive button), all the way to color-specific parameters. For now, we’ll only pass a String for our text message;
  3. Finally, declare the InfoBar composable in your UI tree. Similarly, there are multiple parameters available for you to customize, but this time we only pass the required arguments:
    • offeredMessage – The message variable we declared and assigned earlier
    • onDismiss – Trailing lambda which is called when the InfoBar is either timed out or dismissed by the user. We always have to null out the InfoBarMessage instance here. This is part of the contract with the library, in order to ensure the expected behavior.

Customization options

Although the previous example shows what you can achieve with the minimum effort required from you, there are also a number of customization options at your disposal.

InfoBar composable signatures

The InfoBar composable has 2 signatures:

  • One for a standard version, which already has a layout defined, inspired by the Material design Snackbar. This composable has multiple parameters exposed, allowing for increased customizability of the predefined standard layout.
  • One for a generic version, allowing to pass a composable layout defined in the client app.

Most importantly, make sure to check the GitHub repository readme file, for all the available options.

What about animations?

At the time of writing this article, the official Snackbar implementation does not expose ways for us to easily customize the animation type and animation duration, thus being stuck with a Fade + Scale combo timed at 150ms for the enter animation and 75ms for the exit animation. While these are the values InfoBar also uses by default, in order to feel seamless and familiar to the end-user, you also have the option to customize these aspects. Therefore, some relevant parameters for animations are listed below:

  • Alter the animation type:
    • fadeEffect, fadeEffectEasing
    • scaleEffect, scaleEffectEasing
    • slideEffect, slideEffectEasing
  • Change the transition duration:
    • enterTransitionMillis
    • exitTransitionMillis

Using the generic composable

If the standard InfoBar signature does not entirely meet your requirements in terms of layout, you can use the generic InfoBar signature, which allows you to pass a custom layout composable. For instance, this is just an implementation example, feel free to get as creative as you want. Here are the general steps you need to follow:

1. Extend the BaseInfoBarMessage abstract class and define your custom message data structure:

class CustomMessage(
    val textString: String,
    val icon: ImageVector,
    val iconColor: Color,
    val textColor: Color = Color.Unspecified,
    override val backgroundColor: Color? = null,
    override val displayTimeSeconds: Int? = 4,
) : BaseInfoBarMessage() {
    override val containsControls: Boolean = false
}

2. Declare the content composable that defines your layout:

val content: @Composable (CustomMessage) -> Unit = { message ->
    Row {
        Icon(
            modifier = Modifier.padding(8.dp).align(Alignment.CenterVertically),
            imageVector = message.icon,
            contentDescription = null,
            tint = message.iconColor
        )
        Text(
            modifier = Modifier.align(Alignment.CenterVertically),
            text = message.textString,
            color = message.textColor
        )
    }
}

3. Display the message:

setContent {
    YourAppTheme {
        Box(Modifier.fillMaxSize().padding(16.dp)) {
            var message: CustomMessage? by remember { mutableStateOf(null) }
            Button(
                modifier = Modifier.align(Alignment.Center),
                onClick = { 
                    message = CustomMessage(
                        textString = "This is a custom message",
                        textColor = Color(0xFF414141),
                        icon = Icons.Rounded.Info,
                        iconColor = Color(0xFF27C54D),
                        backgroundColor = Color(0xFFE3F1E6)
                    )
                }
            ) {
                Text("Show message")
            }
            InfoBar(offeredMessage = message, content = content) {
                message = null
            }
        }
    }
}
InfoBar Compose with custom layout

Sample app

More complex usage examples are available in the sample appDownload from Google Play and check its source code.

InfoBar Compose Sample App

Conclusion

While the Snackbar implementation for Jetpack Compose offered by Google is definitely functional and works great if you use it within a Scaffold, I think the InfoBar Compose library is a decent alternative for developers who want more customization freedom, as well as for those who want to show a Snackbar-style message with minimal coding effort. If you would rather use the Snackbar instead but aren’t sure how to do it, I found a short and to-the-point article that shows you how.

I also have a free 7-Hour Jetpack Compose course* on my YouTube channel, which you can watch here.

(*Chapter 15: Info Bar laid the groundwork and the idea for this library. Starting from that implementation presented in the video, I changed it to support increased customization options, used stable animation APIs, among other improvements and offered it as a stand alone library. 😉)

If you use this library and enjoy it, please support it by starring it on GitHub. 🌟