繁体   English   中英

在 Jetpack Compose 中按百分比偏移 Composable

[英]Offset Composable by percentage in Jetpack Compose

我只是想始终偏移图像的确切数量,而不管用户的屏幕分辨率如何。

我这样试过:

var heightIs by remember { mutableStateOf(0f) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .aspectRatio(
                ratio = 1f
            ).onGloballyPositioned { coordinates ->
                heightIs = (coordinates.size.height.toFloat())
            }
    ) {

        Image(
            painter = painterResource(id = R.drawable.base),
            contentDescription = "Shadow",
            modifier = Modifier.fillMaxSize()
        )
        Image(
            painter = painterResource(id = R.drawable.top_mask_normal),
            contentDescription = "Shadow Stencil",
            colorFilter = ColorFilter.tint(color, BlendMode.SrcAtop),
            modifier = Modifier
                .fillMaxSize()
                .offset(y = ((heightIs * 0.03).toInt()).dp)
        )
}

但是我在不同的屏幕分辨率上得到不同的结果。 我每次都希望它完全相同position 无论用户使用平板电脑还是 480x800 设备

使用这条线heightIs * 0.03).toInt()).dp ,您不会转换为 dp 或密度独立像素。 您正在将 .dp 扩展名添加到像素值的末尾。

要转换为 dp,您需要使用LocalDensity.current.run{heightIs * 0.03).toInt().toDp()}

dp 计算为像素/密度。 如果您的设备有 2.0 密度 100px 应该是 50.dp 但使用现有的 function 您只需将100px更改为100.dp

.dp只返回一个Dp类型 object。 无论屏幕的密度如何,您都希望确保 Composable 移动一个固定的“距离”,但像素的大小是可变的。 您将需要某种转换机制,将您的像素值转换为与设备上的距离相同的值,因为它在您的设备上具有不同的密度。 因此,您需要根据您的首选距离在您的设备上设置值(以像素为单位); 那么您需要将该设备上的值转换为Dp值。 然后,您从转换中获得的值可以在其他任何地方、任何设备上使用,原则上它将返回相同的“长度”。

假设您想要一个Dp ,即设备上 500 像素的与密度无关的像素值。 转换过程是

{ // ComposableScope
  val dips = with(LocalDensity.current) { pixels.toDp() }
}

现在,这个值只是为了得到转换后的像素值到 DPs。 记录这个值,或者通过调试器获取它,或者在屏幕上打印它,或者使用你想要检索这个值的任何方法。 一旦价值掌握在您手中,您就不再需要此代码。 只需使用检索到的值初始化dips变量,它就可以在每个设备上正常工作(原则上)。

也可以看看色雷斯医生的回答

heightIs的问题是在onGlobalPositioned中更新时会引起recomposition。

Compose 提供了布局修饰符来解决该问题。

类似的东西可以工作,而不必使用 state

Box(
    modifier = Modifier
        .fillMaxSize()
        .aspectRatio(
            ratio = 1f
        )
) {

    Image(
        painter = painterResource(id = R.drawable.base),
        contentDescription = "Shadow",
        modifier = Modifier.fillMaxSize()
    )
    Image(
        painter = painterResource(id = R.drawable.top_mask_normal),
        contentDescription = "Shadow Stencil",
        colorFilter = ColorFilter.tint(color, BlendMode.SrcAtop),
        modifier = Modifier
            .fillMaxSize()
            .layout { measurable, constraint ->
                val placeable = measurable.measure(constraint)

                layout(constraint.width, constraint.height) {
                    placeable.placeRelative(
                        x = 0, 
                        y = (constraint.height * 0.03).toInt()
                    )
                }
            }
    )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM