Jetpack Composure SubComposeLayout是如何工作的? [英] Jetpack Compose how does SubcomposeLayout work?

查看:9
本文介绍了Jetpack Composure SubComposeLayout是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 }

它应该根据另一个组件大小重新测量组件,但这段代码的实际作用对我来说是个谜。

  1. subcompose函数如何工作?
  2. slotId有什么意义?我们可以通过某种方式获取slotID吗?

subCompose函数说明

使用给定的slotID对所提供的内容执行子合成。 Params:slotID-表示我们正在组成的槽的唯一ID 变成。如果您有固定数量或插槽,则可以使用枚举作为插槽ID, 或者,如果您有一个项目列表,可以是列表中的索引或其他 其他唯一密钥也可以工作。能够正确匹配内容 在重新测量之间,您应该提供等于 上一次测量时使用的那个。内容-- 定义槽的可组合内容。它可能会释放出多个 布局,在这种情况下,返回的可测量对象列表将具有 多个元素。

谁能解释一下它的含义或/并为SubcomposeLayout提供一个工作样本吗?

推荐答案

它应该根据另一个组件大小重新测量组件...

SubcomposeLayout不重新测量。它允许延迟内容的组成和测量,直到知道来自其父内容的约束,并且可以测量其某些内容,其结果和可以作为参数传递给延迟的内容。上面的示例计算mainContent生成的内容的最大大小,并将其作为参数传递给deferredContent。然后,它测量deferredContent并将mainContentdeferredContent放在一起。

SubcomposeLayout使用SubcomposeLayout的最简单示例是BoxWithConstraints,它只是将从父级收到的约束直接传递到其内容。在布局过程中发生的父框测量之前,框的约束是未知的,因此content的合成被推迟到布局。

类似地,对于上面的示例,mainContentmaxSize直到布局才知道,因此一旦计算出maxSize,就在布局中调用deferredContent。它总是将deferredContent放在mainContent之上,因此假定deferredContent以某种方式使用maxSize,以避免模糊mainContent生成的内容。可能不是可组合的最佳设计,但可组合的目的是为了说明性的,而不是有用的本身。

请注意,subcompose可以在layout块中多次调用。例如,这就是LazyRow中发生的情况。slotId允许SubcomposeLayout跟踪和管理通过调用subcompose创建的合成。例如,如果要从数组生成内容,您可能希望使用数组的索引作为其slotId,从而允许SubcomposeLayout确定在重新组合期间应使用上次生成的subcompose。此外,如果不再使用slotidSubcomposeLayout将处置其相应的组成。

至于slotId的去向,这取决于SubcomposeLayout的调用者。如果内容需要它,则将其作为参数传递。上面的示例不需要它,因为slotId对于deferredContent总是相同的,所以它不需要去任何地方。

这篇关于Jetpack Composure SubComposeLayout是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆