Skip to content

Instantly share code, notes, and snippets.

@Mikkareem
Created April 14, 2024 07:35
Show Gist options
  • Save Mikkareem/8a3cef67534287581399d09e3f8147bf to your computer and use it in GitHub Desktop.
Save Mikkareem/8a3cef67534287581399d09e3f8147bf to your computer and use it in GitHub Desktop.
Custom Drawing of Gradient Animated Circular Progress Bar using Jetpack Compose like we have in Hotstar App
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSizeIn
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.Rect
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.ClipOp
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Composable
private fun CircularProgressBarAnimated(
modifier: Modifier = Modifier,
barColor: Color = Color.Blue
) {
val infiniteTransition = rememberInfiniteTransition(label = "infinite rotation")
val animate by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = 1f,
label = "",
animationSpec = infiniteRepeatable(
animation = tween(1000),
repeatMode = RepeatMode.Restart,
)
)
Canvas(
modifier = modifier.requiredSizeIn(
maxWidth = 100.dp,
maxHeight = 100.dp
)
) {
val thickness = 10.dp.toPx()
val clipPath = Path().apply {
addOval(
Rect(
center = center,
radius = size.width * .5f - thickness
)
)
}
rotate(360f * animate) {
clipPath(
path = clipPath,
clipOp = ClipOp.Difference
) {
drawCircle(
brush = Brush.sweepGradient(
colors = listOf(
Color.Transparent,
barColor.copy(alpha = 0.35f),
barColor.copy(alpha = 0.65f),
barColor
),
center = center
)
)
}
}
}
}
@Preview
@Composable
private fun ProgressPreview() {
Box(modifier = Modifier
.background(Color.White)
.padding(16.dp)) {
CircularProgressBarAnimated(
modifier = Modifier.size(100.dp),
)
}
}
@Mikkareem
Copy link
Author

Screen.Recording.2024-04-14.at.1.06.12.PM.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment