在jetpack Compose时使用Layout
or SubcomposeLayout
您可以使用以下方法来衡量您的可组合项Constraints
limits.
如果有一个固定大小的 Modifier,Modifier.size(500.dp),比方说 Int 中的 1000x1000,如果任何子 Composable 需要具有 1100x1000px 大小,layout
函数应该是
layout(1100, 1100){
}
since Constraints
当 Modifier.size() 或 Modifier.sizeIn(maxWidth, maxHeight) 使用可组合中断和跳跃作为大小之间的差异时, maxWidth=1000 和 maxHeight=1000 作为最大限制Modifier
以及您分配给上面的布局功能的那个。
因此我需要增加大小Modifier
在我将其设置为之前
SubcomposeLayout(
modifier = modifier
) { constraints ->
layout(width, height) {
}
}
这对于任何人来说都是可能的吗Modifier
例如Modifier.increseSize(15.dp)
?我知道没有这样的修饰符,但我需要的是在将其设置为修饰符之前增加修饰符的大小Layout
我所做的是可扩展的 SubcomposeLayout。首先获取其主要内容(图像)的大小,然后将句柄大小添加到内容大小并设置layout(width,height)
函数总大小为句柄和内容之和,大于内容大小或Modifier.size()
,当约束不返回有界的上限宽度或高度来限制测量时,此方法有效。
总布局大小必须大于内容大小,因为可触摸区域应该每四分之一覆盖手柄,以便可以单击,正如您在图像中看到的那样,即使在内容区域手柄之外也可以接收手势。
@Composable
internal fun TransformSubcomposeLayout(
modifier: Modifier = Modifier,
handleRadius: Dp = 15.dp,
mainContent: @Composable () -> Unit,
dependentContent: @Composable (IntSize) -> Unit
) {
val handleRadiusInPx = with(LocalDensity.current) {
handleRadius.roundToPx()
}
SubcomposeLayout(
modifier = modifier
) { constraints ->
// Subcompose(compose only a section) main content and get Placeable
val mainPlaceables: List<Placeable> = subcompose(SlotsEnum.Main, mainContent)
.map {
it.measure(constraints)
}
// Get max width and height of main component
val maxSize =
mainPlaceables.fold(IntSize.Zero) { currentMax: IntSize, placeable: Placeable ->
IntSize(
width = maxOf(currentMax.width, placeable.width),
height = maxOf(currentMax.height, placeable.height)
)
}
// Set sum of content and handle size as total size of this Composable
val width = maxSize.width + 2 * handleRadiusInPx
val height = maxSize.height + 2 * handleRadiusInPx
val dependentPlaceables = subcompose(SlotsEnum.Dependent) {
dependentContent(maxSize)
}.map {
it.measure(constraints)
}
layout(width, height) {
dependentPlaceables.forEach { placeable: Placeable ->
// place Placeables inside content area by offsetting by handle radius
placeable.placeRelative(
(width - placeable.width) / 2,
(height - placeable.height) / 2
)
}
}
}
}
enum class SlotsEnum { Main, Dependent }
我传递了内容大小,这样我就可以调整内容的大小
@Composable
fun TransformLayout(
modifier: Modifier = Modifier,
enabled: Boolean = true,
handleRadius: Dp = 15.dp,
handlePlacement: HandlePlacement = HandlePlacement.Corner,
onDown: (Transform) -> Unit = {},
onMove: (Transform) -> Unit = {},
onUp: (Transform) -> Unit = {},
content: @Composable () -> Unit
) {
TransformSubcomposeLayout(
// ???? !!! I'm not able to pass modifier from function because if it contains
// a Modifier.size() it breaks layout() function
// and because of that i can't set border, zIndex or any other Modifier from
// user. ZIndex must be set here to work, since it works against siblings
modifier = Modifier.border(3.dp, Color.Green),
handleRadius = handleRadius.coerceAtLeast(12.dp),
mainContent = {
// ???? Modifier from user is only used for measuring size
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
content()
}
},
dependentContent = { intSize: IntSize ->
val dpSize = with(LocalDensity.current) {
val rawWidth = intSize.width.toDp()
val rawHeight = intSize.height.toDp()
DpSize(rawWidth, rawHeight)
}
TransformLayoutImpl(
enabled = enabled,
handleRadius = handleRadius,
dpSize = dpSize,
handlePlacement = handlePlacement,
onDown = onDown,
onMove = onMove,
onUp = onUp,
content = content
)
}
)
}
我想使用这个布局
val density = LocalDensity.current
val size = (500 / density.density).dp
TransformLayout(
modifier = Modifier.size(size).border(5.dp, Color.Red).zIndex(100f),
enabled = enabled,
handlePlacement = HandlePlacement.Side
) {
Image(
painter = painterResource(id = R.drawable.landscape1),
contentScale = ContentScale.FillBounds,
contentDescription = "",
)
}
如果我在修改器大小为 500x500 时设置布局(500+, 500+) 并将其设置为 SubcomposeLayout 修改器可组合项未放置在正确的位置。