Jeff
05/27/2021, 2:18 PMAndrew Neal
05/27/2021, 2:26 PMModifier
.
https://github.com/lelandrichardson/compose-dogfooding/blob/main/project-management-app/app/src/main/java/com/example/pmapp/TimelineScreen.kt#L302
And if you want to watch him working on it, starts around here:
Halil Ozercan
05/27/2021, 3:27 PMDaniel
05/27/2021, 6:05 PMDaniel
05/27/2021, 6:05 PMiamthevoid
05/27/2021, 7:17 PMDaniel
05/27/2021, 7:18 PMiamthevoid
05/27/2021, 7:23 PMHalil Ozercan
05/27/2021, 7:23 PMNader Jawad
05/27/2021, 9:30 PM@Composable
fun TransparentChipDemo() {
val backgroundGradient = Brush.linearGradient(
0.0f to Color.Red,
1.0f to Color.Blue
)
val circleCount = 5
val circleColors = listOf(Color.Green, Color.Yellow, Color.Cyan, Color.Magenta, Color.LightGray)
val clearStroke = Stroke(width = 5.0f)
Box(modifier = Modifier.size(300.dp, 150.dp)
.background(backgroundGradient)
.graphicsLayer {
// Slight alpha to force compositing layer
// This is necessary to create an offscreen buffer to draw contents into
// and use the clear blend mode to crop out the content around the circle chips
// that are drawn
// Future versions of compose will have an explicit flag to force compositing to
// an offscreen buffer but for now include a small alpha to force it
alpha = 0.99f
}
.drawBehind {
val circleSize = (size.minDimension / circleCount)
val circleRadius = circleSize / 2
var centerX = size.width / 2 - (circleRadius * (circleCount + 1)) / 2 + circleRadius
for (i in 0 until circleCount) {
val circleOffset = Offset(centerX, size.height / 2)
drawCircle(circleColors[i], circleRadius, circleOffset)
drawCircle(
Color.Black,
circleRadius,
circleOffset,
style = clearStroke,
blendMode = BlendMode.Clear
)
centerX += circleRadius
}
}
)
}
Nader Jawad
05/27/2021, 9:32 PMShaderBrush
using ImageShader
with the given profile image and replacing the drawCircle(circleColors[i]...
call above with that brush instead. I left it as circles here for the sake of example.Nader Jawad
05/27/2021, 11:07 PMImage
composable in this sample for demo sake but you insert any composable within Chip
to get a similar result:
@Composable
fun ChipStack(modifier: Modifier = Modifier) {
val size = 80.dp
val sizeModifier = Modifier.size(size)
val colors = listOf(Color.Green, Color.Yellow, Color.Cyan, Color.Magenta, Color.LightGray)
val width = (size / 2) * (colors.size + 1)
Box(modifier = modifier.size(width, size)
.graphicsLayer {
alpha = 0.99f // slight alpha to force compositing layer
},
) {
var offset = 0.dp
for (color in colors) {
Chip(strokeWidth = 10.0f, sizeModifier.offset(offset)) {
Image(ColorPainter(color), contentDescription = null)
}
offset += size / 2
}
}
}
@Composable
fun Chip(
strokeWidth: Float,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val stroke = remember(strokeWidth) {
Stroke(width = strokeWidth)
}
Box(modifier = modifier
.drawWithContent {
drawContent()
drawCircle(
Color.Black,
size.minDimension / 2,
size.center,
style = stroke,
blendMode = BlendMode.Clear
)
}.graphicsLayer {
clip = true
shape = CircleShape
}
) {
content()
}
}
@Composable
fun ChipStackDemo() {
Box(modifier = Modifier.fillMaxSize().wrapContentSize()) {
val backgroundGradient = remember {
Brush.linearGradient(
0.0f to Color.Red,
1.0f to Color.Blue
)
}
ChipStack(Modifier.background(backgroundGradient))
}
}
Nader Jawad
05/27/2021, 11:09 PMChachako
05/28/2021, 2:08 AMJeff
06/03/2021, 4:39 PMbrandonmcansh
11/04/2021, 1:05 AMNader Jawad
08/24/2022, 7:34 PMLeland Richardson [G]
08/24/2022, 8:01 PMNader Jawad
05/03/2023, 1:50 AMalpha = 0.99f
workaround in the code snippet above is no longer necessary. With compose 1.4 you can specify CompositingStrategy.Always
to force rendering of a graphicsLayer
into an off screen buffer for masking purposesColton Idle
05/03/2023, 4:46 AMNader Jawad
05/04/2023, 2:32 PMNader Jawad
05/04/2023, 2:35 PMColton Idle
05/04/2023, 3:53 PMNader Jawad
05/04/2023, 3:54 PMCompositingStrategy.Offscreen
now. "Always" was the original nameColton Idle
05/04/2023, 4:12 PM