Last active
September 17, 2024 16:40
-
-
Save nirbhayph/5adaa4976a231f1c07f3d12d4ee711a1 to your computer and use it in GitHub Desktop.
Unleashing Creativity with Custom Modifiers in Android Jetpack Compose
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.compose.animation.core.LinearEasing | |
import androidx.compose.animation.core.RepeatMode | |
import androidx.compose.animation.core.animateFloat | |
import androidx.compose.animation.core.infiniteRepeatable | |
import androidx.compose.animation.core.keyframes | |
import androidx.compose.animation.core.rememberInfiniteTransition | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.composed | |
import androidx.compose.ui.draw.drawWithContent | |
import androidx.compose.ui.graphics.Brush | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.graphicsLayer | |
import androidx.compose.ui.layout.layout | |
/** | |
* Created by Nirbhay Pherwani on 8/18/2023. | |
* Linktree - https://linktree.com/nirbhaypherwani | |
*/ | |
fun Modifier.gradientBackground(colors: List<Color>): Modifier = composed { | |
drawWithContent { | |
drawRect( | |
brush = Brush.verticalGradient(colors), | |
size = size | |
) | |
drawContent() | |
} | |
} | |
fun Modifier.aspectRatio(ratio: Float): Modifier = composed { | |
layout { measurable, constraints -> | |
val width = constraints.maxWidth | |
val height = (width / ratio).toInt() | |
val placeable = measurable.measure( | |
constraints.copy(minHeight = height, maxHeight = height) | |
) | |
layout(width, height) { | |
placeable.place(0, 0) | |
} | |
} | |
} | |
fun Modifier.floatingActionButtonAnimator( | |
animationDurationMillis: Int = 1500, | |
rotationAngle: Float = 180f | |
): Modifier = composed { | |
val transition = rememberInfiniteTransition(label = "") | |
val animatedProgress = transition.animateFloat( | |
initialValue = 0f, | |
targetValue = 1f, | |
animationSpec = infiniteRepeatable( | |
animation = keyframes { | |
durationMillis = animationDurationMillis | |
0f at 0 with LinearEasing | |
1f at 0 with LinearEasing | |
0f at 1 with LinearEasing | |
}, | |
repeatMode = RepeatMode.Restart | |
), label = "" | |
) | |
val rotation = animatedProgress.value * rotationAngle | |
this.then( | |
Modifier | |
.graphicsLayer(rotationZ = rotation) | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sample Usages (Imports not included) | |
/** | |
* Created by Nirbhay Pherwani on 8/18/2023. | |
* Linktree - https://linktree.com/nirbhaypherwani | |
*/ | |
// Usage #1 | |
Column( | |
modifier = Modifier | |
.gradientBackground(listOf(Color.Green, Color.Red)) | |
.fillMaxSize(), | |
horizontalAlignment = Alignment.CenterHorizontally, | |
verticalArrangement = Arrangement.Center | |
) { | |
FloatingActionButton( | |
onClick = { /* Handle click here */ }, | |
modifier = Modifier | |
.floatingActionButtonAnimator(animationDurationMillis = 700, rotationAngle = 360f) | |
.size(108.dp), | |
containerColor = Color.Red | |
) { | |
Icon(Icons.Filled.Add, contentDescription = "Add", tint = Color.White) | |
} | |
FloatingActionButton( | |
onClick = { /* Handle click here */ }, | |
modifier = Modifier | |
.floatingActionButtonAnimator(animationDurationMillis = 3000, rotationAngle = 90f) | |
.size(108.dp), | |
containerColor = Color.Blue | |
) { | |
Icon(Icons.Filled.Build, contentDescription = "Build", tint = Color.White) | |
} | |
FloatingActionButton( | |
onClick = { /* Handle click here */ }, | |
modifier = Modifier | |
.floatingActionButtonAnimator(animationDurationMillis = 5000, rotationAngle = 270f) | |
.size(108.dp), | |
containerColor = Color.Green | |
) { | |
Icon(Icons.Filled.Call, contentDescription = "Call", tint = Color.White) | |
} | |
} | |
// Usage #2 | |
Column( | |
modifier = Modifier | |
.gradientBackground(listOf(Color.Blue, Color.Green, Color.White)) | |
.fillMaxSize(), | |
horizontalAlignment = Alignment.CenterHorizontally, | |
verticalArrangement = Arrangement.Center, | |
) { | |
Text("Custom modifier was applied on me!") | |
} | |
// Usage #3 | |
Column( | |
modifier = Modifier | |
.gradientBackground(listOf(Color.Blue, Color.White)) | |
.fillMaxSize(), | |
horizontalAlignment = Alignment.CenterHorizontally, | |
verticalArrangement = Arrangement.Center, | |
) { | |
Image( | |
painter = painterResource(id = R.drawable.stock_wallapaper), | |
contentDescription = null, | |
modifier = Modifier | |
.aspectRatio(16/9f) | |
.fillMaxWidth(), // modify as needed | |
contentScale = ContentScale.Crop | |
) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment