Jetpack Compose gets official support for Marquee 🎉! Here’s how to use it!
It’s just so easy to implement!
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!"
)
}
}
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))
}
}
}
}
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!"
)
}
}
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 🙂
Some of my other articles that you might be interested in: