SUBSCRIBE NOW![avatar]()
I always learn something just by skimming it that makes me want to bookmark the issue now and dig deeper later

SUBSCRIBE NOW![avatar]()
Keep up the good work with the newsletter 💪 I really enjoy it

SUBSCRIBE NOW![avatar]()
Dispatch is a must read for Android devs today and my go-to for keeping up with all things Jetpack Compose

SUBSCRIBE NOW![avatar]()
Dispatch has been my go-to resource as it's packed with useful information while being fun at the same time

SUBSCRIBE NOW![avatar]()
The content is light, fun, and still useful. I especially appreciate the small tips that are in each issue

SUBSCRIBE NOW![avatar]()
I truly love this newsletter ❤️🔥 Spot on content and I know there's a lot of effort that goes behind it

SUBSCRIBE NOW![avatar]()
Thanks for taking the time and energy to do it so well

JetpackCompose.app's Newsletter![avatar]()
I always learn something just by skimming it that makes me want to bookmark the issue now and dig deeper later

JetpackCompose.app's Newsletter![avatar]()
Keep up the good work with the newsletter 💪 I really enjoy it

JetpackCompose.app's Newsletter![avatar]()
Dispatch is a must read for Android devs today and my go-to for keeping up with all things Jetpack Compose

JetpackCompose.app's Newsletter![avatar]()
Dispatch has been my go-to resource as it's packed with useful information while being fun at the same time

JetpackCompose.app's Newsletter![avatar]()
The content is light, fun, and still useful. I especially appreciate the small tips that are in each issue

JetpackCompose.app's Newsletter![avatar]()
I truly love this newsletter ❤️🔥 Spot on content and I know there's a lot of effort that goes behind it

JetpackCompose.app's Newsletter![avatar]()
Thanks for taking the time and energy to do it so well

Worm Page Indicator
Author: Denis Ismailaj
Animated worm page indicator that's typically used with view pagers and intro sliders.

import androidx.compose.animation.core.animateDpAsState | |
import androidx.compose.foundation.Canvas | |
import androidx.compose.foundation.layout.Arrangement | |
import androidx.compose.foundation.layout.Row | |
import androidx.compose.foundation.layout.requiredWidth | |
import androidx.compose.foundation.layout.size | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.getValue | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.geometry.CornerRadius | |
import androidx.compose.ui.geometry.Size | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.unit.Dp | |
import androidx.compose.ui.unit.dp | |
@Composable | |
fun WormPageIndicator( | |
totalPages: Int, | |
currentPage: Int, | |
modifier: Modifier = Modifier, | |
indicatorSize: Dp = 6.dp, | |
color: Color = Color.White, | |
spacing: Dp = indicatorSize, | |
selectedMultiplier: Int = 3 | |
) { | |
assert( | |
value = currentPage in 0 until totalPages, | |
lazyMessage = { "Current page index is out of range." } | |
) | |
val rowWidth = (indicatorSize * (selectedMultiplier + (totalPages - 1))) + (spacing * (totalPages - 1)) | |
Row( | |
modifier = modifier | |
.requiredWidth(rowWidth), | |
horizontalArrangement = Arrangement.SpaceBetween | |
) { | |
for (i in 0 until totalPages) { | |
val selected = i == currentPage | |
val height = indicatorSize | |
val width: Dp by animateDpAsState( | |
if (selected) indicatorSize * selectedMultiplier else indicatorSize | |
) | |
Canvas( | |
modifier = Modifier | |
.size(width, height), | |
onDraw = { | |
drawRoundRect( | |
color = color, | |
cornerRadius = CornerRadius(height.toPx() / 2), | |
size = Size(width.toPx(), height.toPx()) | |
) | |
} | |
) | |
} | |
} | |
} |
Have a project you'd like to submit? Fill this form, will ya!
If you like this snippet, you might also like:
Maker OS is an all-in-one productivity system for developers
I built Maker OS to track, manage & organize my life. Now you can do it too!