SubcomposeLayout移除可放置项异常:关闭后bottom组件仍在组件树
问题原因
你当前的代码中,无论expanded状态是true还是false,都会执行subcompose(ExpandedItemSlot.BOTTOM, bottom)——这一步已经完成了bottom对应Composable的组合(composition)流程,所以哪怕你不在layout块中放置它,它依然会存在于组件树里,只是处于「未放置」状态,布局检查器会正常显示它。
解决方案
要真正移除bottom组件,核心是仅在expanded为true时才对bottom执行subcompose操作,修改后的代码如下:
@Composable fun ExpandItem( top: @Composable () -> Unit, bottom: @Composable () -> Unit, expanded: Boolean, modifier: Modifier = Modifier, ) { SubcomposeLayout(modifier = modifier) { constraints -> val topPlaceable = subcompose(ExpandedItemSlot.TOP, top).map { measurable -> measurable.measure(constraints) }.first() // 仅在展开状态下才组合bottom内容 val bottomPlaceable = if (expanded) { subcompose(ExpandedItemSlot.BOTTOM, bottom).map { measurable -> measurable.measure(constraints) }.first() } else { null } val width = maxOf( topPlaceable.width, bottomPlaceable?.width ?: topPlaceable.width ) val height = if(expanded) { topPlaceable.height + (bottomPlaceable?.height ?: 0) } else { topPlaceable.height } layout(width, height) { topPlaceable.placeRelative(0, 0) bottomPlaceable?.let { it.placeRelative(0, topPlaceable.height) } } } } private enum class ExpandedItemSlot { TOP, BOTTOM }
补充说明
SubcomposeLayout的subcompose方法是触发Composable组合的关键:只要调用该方法,对应的内容就会进入组合流程,这和后续是否执行placeRelative(布局阶段操作)无关。组件树的存在与否,取决于组合阶段是否执行,而非布局阶段是否放置。
内容的提问来源于stack exchange,提问作者Fillipe Duoli
相关产品推荐
相关产品推荐

