I built a screen with Compose MotionLayout.
My dependencies are:
androidx.constraintlayout:constraintlayout-compose:1.0.1- Platform
dev.chrisbanes.compose:compose-bom:2023.02.00-beta03 androidx.compose.material3:material3:1.2.0-alpha06- Compose
1.5.0
I have an Image defined as:
MotionLayout(
/* ... */
motionScene = MotionScene(motionScene),
progress = progress
) {
Image(
modifier = Modifier
.clip(avatarShape)
.layoutId("avatar"),
painter = painterResource(id = R.drawable.chat_pattern_png),
contentDescription = null,
contentScale = ContentScale.Crop
)
/* ... */
}
Which is constrained like this:
{
ConstraintSets: {
start: {
avatar: {
width: 45,
height: 45,
start: ['parent', 'start', 16],
top: ['parent', 'top', 16]
},
// ...
},
end: {
avatar: {
width: 'parent',
height: '1:1',
start: ['parent', 'start'],
top: ['parent', 'top'],
},
// ...
}
}
}
This results in almost what I want:
But I needed to add some gradients to make content that ends up above the image readable. I didn't want to add Boxes to my layout so I drew above the image with a drawWithContent modifier:
val breakpointTransitionProgress by animateFloatAsState(
targetValue = if (progress <= .7f) 0f else 1f
)
//...
Image(
modifier = Modifier
.clip(avatarShape)
.drawWithContent {
drawContent()
drawRect(
brush = Brush.verticalGradient(
0f to Color.Black.copy(.4f),
1f to Color.Transparent,
endY = size.height * .3f * breakpointTransitionProgress
),
size = size.copy(height = size.height * .3f * breakpointTransitionProgress)
)
drawRect(
brush = Brush.verticalGradient(
0f to Color.Transparent,
1f to Color.Black.copy(.4f),
startY = size.height * lerp(1f, .7f, breakpointTransitionProgress),
),
size = size.copy(height = size.height * .3f),
topLeft = Offset(
x = 0f,
y = size.height * lerp(1f, .7f, breakpointTransitionProgress)
)
)
}
.layoutId("avatar"),
painter = painterResource(id = R.drawable.chat_pattern_png),
contentDescription = null,
contentScale = ContentScale.Crop
)
Which is where I encountered the most bizarre bug I've ever seen. Look at the icons in Bottom Navigation - they flicker, as if those gradients are applied to them too.
I can't even begin to guess WTF is happening here since this MotionLayout is a destination inside a NavHost inside the content slot of the topmost Scaffold, while BottomNavigationItems are inside the bottomBar slot of the same Scaffold. I just can't see how drawing above the image can influence them.
What could I have done wrong? Is this a dependency bug? Should I report it?

