Open CalamityDeadshot opened 2 years ago
Which version of the library are you using?
Have you tried removing the wrapContentWidth/Height modifiers? Ie: Just Modifier.layoutId("title")
MotionLayout will default to wrapContent.
I am using constraintlayout-compose:1.0.0
.
I put wrapContentWidth
on the text because without it another problem arises: the text is being inconsistently clipped.
Here I assigned "Long text" as title's value:
It is rendered correctly after recomposition. I believe it belongs to a separate issue.
But yes, margin does not appear if I remove wrapContentWidth
.
Taking another look at this, not sure if this is what you intended but it seems to do the trick in terms of the expected layout.
@Preview
@Composable
private fun Issue507Preview() {
var toEnd by remember { mutableStateOf(false) }
val progress by animateFloatAsState(
targetValue = if(toEnd) 1f else 0f,
tween(2500)
)
Column {
Button(onClick = {
toEnd = !toEnd
}) {
Text(text = "Run")
}
Issue507(progress = progress)
}
}
@OptIn(ExperimentalMotionApi::class)
@Composable
fun Issue507(progress: Float) {
MotionLayout(
modifier = Modifier
.background(Color.LightGray)
.fillMaxWidth()
.height(lerp(150.dp, 50.dp, progress)),
motionScene = MotionScene(content = """
{
ConstraintSets: {
start: {
title: {
top: ['parent', 'top'],
start: ['parent', 'start'],
end: ['parent', 'end'],
bottom: ['options', 'top', 24],
custom: {
fontSize: 32,
fontWeight: 400
}
},
options: {
end: ['parent', 'end', 0],
bottom: ['content', 'top', 15]
},
content: {
width: 'spread', height: 'wrap',
start: ['parent', 'start'],
end: ['parent', 'end'],
bottom: ['parent', 'bottom', 0]
}
},
end: {
title: {
top: ['parent', 'top', 0],
start: ['parent', 'start', 16],
bottom: ['content', 'top', 0],
custom: {
fontSize: 20,
fontWeight: 500
}
},
options: {
end: ['parent', 'end', 0],
bottom: ['content', 'top', 0],
top: ['parent', 'top', 0]
},
content: {
width: 'spread', height: 'wrap',
start: ['parent', 'start'],
end: ['parent', 'end'],
bottom: ['parent', 'bottom', 0]
}
}
},
Transitions: {
default: {
from: 'start',
to: 'end'
}
}
}
""".trimIndent()),
progress = progress
) {
Text(
text = "This is a very long text",
modifier = Modifier
.layoutId("title")
.wrapContentWidth(unbounded = true), // Seems to measure the text more accurately
color = MaterialTheme.colors.onSurface,
maxLines = 1, // maxLines and no softWrap help a bit with clipping
softWrap = false,
fontWeight = FontWeight(motionInt("title", "fontWeight")),
fontSize = motionFontSize("title", "fontSize")
)
Options(
modifier = Modifier
.layoutId("options")
.background(Color.Blue)
)
Tabs(
Modifier
.layoutId("content")
.background(Color.Red)
)
}
}
@Composable
private fun Options(modifier: Modifier = Modifier) {
Row(modifier = modifier) {
Icon(imageVector = Icons.Default.Settings, contentDescription = null)
Icon(imageVector = Icons.Default.Notifications, contentDescription = null)
Icon(imageVector = Icons.Default.Filter, contentDescription = null)
Icon(imageVector = Icons.Default.Search, contentDescription = null)
}
}
@Composable
private fun Tabs(modifier: Modifier = Modifier) {
Row(modifier = modifier,horizontalArrangement = Arrangement.SpaceEvenly) {
Text(text = "All")
Text(text = "My")
}
}
There seems to be two issues while animating the text that results in the clipping.
In any case, thanks for the report, at least for the clipping I understand a little better what's happening.
I have the following
ConstraintSet
s for theMotionLayout
:and the following scene:
This is a correctly rendered
StartConstraintSet
: And this is a correctly renderedEndConstraintSet
:However, after the whole app bar is recomposed,
title
obtains what looks like a margin:This doesn't happen when simply scaling the text, so it must be its bounding box returning to
32sp
value from before the transformation. I cannot explain this behavior with anything else.