Search code examples
androidandroid-jetpack-composeandroid-motionlayout

Problem between SharedTransitionLayout and MotionLayout in Jetpack Compose


Currently my application uses SharedTransitionLayout to make an animation from the title of the SplashScreen and the toolbar of my application that also includes this title.

This works perfectly, except that I discovered a problem when I tried to use MotionLayout to make a collapsing toolbar with Jetpack Compose.

If MotionLayout is inside SharedTransitionLayout, it is not shown, but if not, it is shown, is it a known bug?

@OptIn(ExperimentalSharedTransitionApi::class)
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MotionEventExampleTheme {

                SharedTransitionLayout {

                    Column {

                        var progress by remember {
                            mutableFloatStateOf(0f)
                        }

                        ProfileHeader(
                            progress = progress
                        )

                        Spacer(
                            modifier = Modifier.height(32.dp)
                        )

                        Slider(
                            value = progress,
                            onValueChange = {
                                progress = it
                            },
                            modifier = Modifier.padding(
                                horizontal = 32.dp
                            )
                        )
                    }
                }
            }
        }
    }
}

@OptIn(ExperimentalMotionApi::class)
@Composable
fun ProfileHeader(progress: Float) {

    val context = LocalContext.current

    val motionScene = remember {
        context.resources
            .openRawResource(R.raw.motion_scene)
            .readBytes()
            .decodeToString()
    }

    MotionLayout(
        motionScene = MotionScene(content = motionScene),
        progress = progress,
        modifier = Modifier.fillMaxWidth()
    ) {
        val properties = motionProperties(id = "recipe_image")
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.DarkGray)
                .layoutId("box")
        )
        Image(
            painter = painterResource(id = R.drawable.picture),
            contentDescription = null,
            modifier = Modifier
                .clip(CircleShape)
                .border(
                    width = 2.dp,
                    color = properties.value.color("background"),
                    shape = CircleShape
                )
                .layoutId("recipe_image")
        )
        Text(
            text = "Philipp Lackner",
            fontSize = 24.sp,
            modifier = Modifier.layoutId("recipe_title"),
            color = properties.value.color("background")
        )
    }
}

It's a video with example:

https://imgur.com/a/nGjI3KZ


Solution

  • For anyone who might find it useful, I opened an issue on Google and it was a problem of theirs that is fixed in version 1.1.0-alpha14 of the constraint library:

    androidx-constraint = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version.ref = "constraint" }