Jetpack Composure SubComposeLayout是如何工作的? [英] Jetpack Compose how does SubcomposeLayout work?
问题描述
如official documents中所示,有一个名为SubposeLayout的布局定义为
布局的模拟,允许对实际内容进行细分 在测量阶段,例如使用计算的值 在测量期间作为子项组成的参数。可能的用例:
您需要知道父级在 组合,不能仅使用自定义布局或 布局修改器。看见 Androidx.compose.foundation.layout.BoxWithConstraints. 要在合成期间使用一个子级的大小 第二个孩子。您希望根据可用大小懒洋洋地排版项目。为 例如,您有一个包含100个项目的列表,而不是将所有 你只能合成那些当前可见的(比如5个 它们),并在滚动组件时组成下一项。
我用SubcomposeLayout
关键字搜索Stackoverflow,但找不到任何有关它的信息,创建了这个示例代码,并从官方文档复制了大部分代码,以测试和了解它是如何工作的
@Composable
private fun SampleContent() {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
SubComponent(
mainContent = {
Text(
"MainContent",
modifier = Modifier
.background(Color(0xffF44336))
.height(60.dp),
color = Color.White
)
},
dependentContent = {
val size = it
println("🤔 Dependent size: $size")
Column() {
Text(
"Dependent Content",
modifier = Modifier
.background(Color(0xff9C27B0)),
color = Color.White
)
}
}
)
}
}
@Composable
private fun SubComponent(
mainContent: @Composable () -> Unit,
dependentContent: @Composable (IntSize) -> Unit
) {
SubcomposeLayout { constraints ->
val mainPlaceables = subcompose(SlotsEnum.Main, mainContent).map {
it.measure(constraints)
}
val maxSize = mainPlaceables.fold(IntSize.Zero) { currentMax, placeable ->
IntSize(
width = maxOf(currentMax.width, placeable.width),
height = maxOf(currentMax.height, placeable.height)
)
}
layout(maxSize.width, maxSize.height) {
mainPlaceables.forEach { it.placeRelative(0, 0) }
subcompose(SlotsEnum.Dependent) {
dependentContent(maxSize)
}.forEach {
it.measure(constraints).placeRelative(0, 0)
}
}
}
}
enum class SlotsEnum { Main, Dependent }
它应该根据另一个组件大小重新测量组件,但这段代码的实际作用对我来说是个谜。
subcompose
函数如何工作?slotId
有什么意义?我们可以通过某种方式获取slotID吗?
subCompose
函数说明
使用给定的slotID对所提供的内容执行子合成。 Params:slotID-表示我们正在组成的槽的唯一ID 变成。如果您有固定数量或插槽,则可以使用枚举作为插槽ID, 或者,如果您有一个项目列表,可以是列表中的索引或其他 其他唯一密钥也可以工作。能够正确匹配内容 在重新测量之间,您应该提供等于 上一次测量时使用的那个。内容-- 定义槽的可组合内容。它可能会释放出多个 布局,在这种情况下,返回的可测量对象列表将具有 多个元素。
谁能解释一下它的含义或/并为SubcomposeLayout
提供一个工作样本吗?
推荐答案
它应该根据另一个组件大小重新测量组件...
SubcomposeLayout
不重新测量。它允许延迟内容的组成和测量,直到知道来自其父内容的约束,并且可以测量其某些内容,其结果和可以作为参数传递给延迟的内容。上面的示例计算mainContent
生成的内容的最大大小,并将其作为参数传递给deferredContent
。然后,它测量deferredContent
并将mainContent
和deferredContent
放在一起。
SubcomposeLayout
使用SubcomposeLayout
的最简单示例是BoxWithConstraints,它只是将从父级收到的约束直接传递到其内容。在布局过程中发生的父框测量之前,框的约束是未知的,因此content
的合成被推迟到布局。类似地,对于上面的示例,mainContent
的maxSize
直到布局才知道,因此一旦计算出maxSize
,就在布局中调用deferredContent
。它总是将deferredContent
放在mainContent
之上,因此假定deferredContent
以某种方式使用maxSize
,以避免模糊mainContent
生成的内容。可能不是可组合的最佳设计,但可组合的目的是为了说明性的,而不是有用的本身。
请注意,subcompose
可以在layout
块中多次调用。例如,这就是LazyRow
中发生的情况。slotId
允许SubcomposeLayout
跟踪和管理通过调用subcompose
创建的合成。例如,如果要从数组生成内容,您可能希望使用数组的索引作为其slotId
,从而允许SubcomposeLayout
确定在重新组合期间应使用上次生成的subcompose
。此外,如果不再使用slotid
,SubcomposeLayout
将处置其相应的组成。
至于slotId
的去向,这取决于SubcomposeLayout
的调用者。如果内容需要它,则将其作为参数传递。上面的示例不需要它,因为slotId
对于deferredContent
总是相同的,所以它不需要去任何地方。
这篇关于Jetpack Composure SubComposeLayout是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!