Jetpack Compose gets official support for Marquee 🎉! Here’s how to use it!

It’s just so easy to implement!

The Android Developer
5 min readMar 23, 2023

Introduction

Hello everyone👋! Hope you’re doing well! The developers at Google just released an update to all the Jetpack Compose libraries. There were a lot of awesome changes. Among them was the ability to add the marquee effect to any composable. In this short article, I will show you how to apply the marquee effect to any composable in your Android app.

Setup

The marquee modifier is available from version 1.4.0 of the androidx.compose.foundation:foundation dependency. If you use either of the following dependencies — androidx.compose.material3:material3 or androidx.compose.material:material , then, you can just upgrade to 1.4.0 of the said libraries. This is because both of the material dependencies depend upon the foundation module. So, upgrading their version will implicitly update the version of the foundation module as well.

dependencies {
// if you're using material design 2
implementation 'androidx.compose.material3:material:1.4.0'
// if you're using material design 3
implementation 'androidx.compose.material3:material3:1.4.0'
// if you're just using foundation directly
implementation 'androidx.compose.foundation:foundation:1.4.0'
}

Alternatively, if you’re using the compose Bill Of Materials(BOM), then upgrade the version of the bom to 2023.03.00.

dependencies {
def composeBom = platform('androidx.compose:compose-bom:2023.03.00')
implementation composeBom
androidTestImplementation composeBom
}

Applying the Marquee effect to a text composable

Applying the Marquee effect to a composable is extremely straightforward. Just use the basicMarquee() modifier on the composable that you want to add the marquee effect. It’s as simple as that! At the time of writing this, the basicMarquee() modifier is annotated with the @ExperimentalFoundationApi annotation. So, you can either opt-in using the @OptIn(ExperimentalFoundationApi::class) annotation, or, propagate it, using the @ExperimentalFoundationApi on the composable that is using the modifier. Here’s an example.

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun MarqueeEffect() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
modifier = Modifier.basicMarquee(),
text = "Compose has finally added support for Marquee! It's soo easy to implement!"
)
}
}
Marquee modifier being applied to a text composable

Applying the marquee modifier to a non-text composable

Yes, you read that right! The marquee modifier, being a modifier, can also be applied to any composable, not just the text composable. Here’s an example of using it on a non-text composable.

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun MarqueeEffect() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Row(modifier = Modifier.basicMarquee()) {
repeat(30) {
Box(
modifier = Modifier
.size(30.dp)
.background(Color.Red)
)
Spacer(modifier = Modifier.width(8.dp))
}
}
}
}
Marquee modifier being applied to a non-text composable

Couple of things to know about the basicMarquee() modifier

  • The modifier will apply the effect, if and only if, the content of the composable to which the modifier is getting applied, is too wide to fit in the available space. The modifier has no effect if the content is able to fit within the available space.
  • If the animation is running, it will restart when any of the parameters passed to the modifier changes, or the size of the content/container composable changes.
  • It’s not really a good idea to keep the marquee animation running indefinitely because, it might affect the battery life, and also, from a UX point of view, it just doesn't make sense. A good default would be to run the animation, only when the user indicates that he/she wants to see more of the content, by, for example, clicking on it.

Applying the marquee effect in a more realistic manner

As I mentioned, it’s not really optimal to keep the marquee animation running indefinitely. One improvement would be to run the animation only when the composable is focused. This can be achieved by leveraging the animationMode param of the modifier.

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun MarqueeEffect() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
val focusRequester = remember { FocusRequester() }
Text(
modifier = Modifier
.basicMarquee(animationMode = MarqueeAnimationMode.WhileFocused)
.focusRequester(focusRequester)
.focusable()
.clickable { focusRequester.requestFocus() },
text = "Compose has finally added support for Marquee! It's soo easy to implement!"
)
}
}
Enabling the Marquee effect only when the composable is focused

Conclusion

And, that wraps up this blog post about the basicMarquee() modifier 🎉! We’ve just scratched the surface here, don’t forget to check out the different parameters of this modifier, it allows us to add a lot of customizations to the behavior of the modifier!

As always, hopefully, you found this blog post helpful! If you liked this article, feel free to check out my other articles as well. I would like to thank you for taking the time to read this article😊. I wish you the best of luck! Happy coding 👨‍💻! Go create some awesome Android apps 👨‍💻! Cheers!

If you really liked my article and want to support me, you can do so, by clicking this link. Thank you so much for being generous ❤️, it really motivates me to keep going, and it helps me to keep my articles free for anyone to read. If you don’t feel like supporting, that’s fine too! The fact that you took some time off your schedule to read my article means a lot to me. Thank you 🙂

--

--

The Android Developer

| A very passionate Android Developer 💚 | An extreme Kotlin fanatic 💜 | A huge fan of Jetpack Compose 💙| Focused on making quality blog posts 📝 |