You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中SharedTransitionLayout与MotionLayout兼容问题问询

问题

我用SharedTransitionLayout实现了启动页标题到应用工具栏标题的转场动画,效果正常。但尝试用MotionLayout实现折叠工具栏时发现,若将MotionLayout置于SharedTransitionLayout内则无法显示,移出则正常,请问这是已知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")
        )
    }
}
解答

这是Jetpack Compose中SharedTransitionLayout与MotionLayout共存的已知兼容性问题,属于Experimental API阶段的局限:

  • 核心原因:SharedTransitionLayout的内部布局拦截逻辑会干扰MotionLayout的测量、布局流程,两者都依赖复杂的状态驱动布局更新,嵌套时会出现状态冲突或布局计算异常,导致MotionLayout无法正常渲染。
  • 官方在Compose Motion 1.3.0及以上版本中修复了部分类似嵌套问题,但仍存在边缘场景的兼容性问题。

可行解决方案:

  1. 调整层级结构:将SharedTransitionLayout作为MotionLayout的子组件,仅对需要共享转场的标题元素使用SharedTransitionScope,避免顶层嵌套。
  2. 局部共享转场:不使用顶层SharedTransitionLayout,而是通过rememberSharedTransitionState和sharedTransition修饰符,仅为目标标题元素启用共享转场功能。
  3. 升级依赖版本:确保项目中compose-motion依赖版本至少为1.3.0,部分旧版本的嵌套问题已被官方修复。

内容的提问来源于stack exchange,提问作者Ludiras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:58:25