如何在Android Jetpack Compose中将Dp转换为像素?

66

大多数Jetpack Compose API使用Dp作为尺寸单位,但有时需要像素值。如何将dp值转换为px?例如,有一个graphicsLayer()修饰符,它可以接受以像素为单位的translationX/Y参数。

2个回答

173

toPx()roundToPx()是由Density接口定义的方法,您可以像这样使用它:

import androidx.compose.ui.platform.LocalDensity

val pxValue = with(LocalDensity.current) { 16.dp.toPx() }

// or

val pxValue = LocalDensity.current.run { 16.dp.toPx() }

如果你是 Kotlin 语言的新手,这样的表达可能会让你感到困惑,所以让我们来分解一下并看看它是如何工作的。toPx()扩展函数,属于 Dp 类,你可以把它看作是 Dp 类的方法。但由于 toPx() 定义在 Density 接口内部,除非你提供一个密度作为接收器,否则无法使用它。最后,你可以从名为 LocalDensityCompositionLocal 中获取当前密度。


1
环境密度是否将被称为CompositionLocalDensity?(实际上,现在它被称为LocalDensity,我已经检查过了) - EpicPandaForce
@EpicPandaForce 谢谢!确实,从 alpha-12 开始 Ambient 被命名为 CompositionLocal,我已更新答案。 - Valeriy Katkov
1
语法解释得非常好,我来这里就是为了寻找那种神奇的东西! - user2297550
9
如果您想将像素转换为Dp,则可以使用LocalDensity.current.run { 16.toDp() } - sea cat
1
奇怪,它需要@Composable上下文来将dp转换为px。为什么? - Michael Abyzov
如果在@Composable上下文之外创建自定义MeasurePolicy,我该怎么办? - Michael Abyzov

29

@Valeriy的回答绝对是正确的方法,但如果您希望它稍微简洁一些或者有很多转换需要做的话,您可以创建扩展函数:

@Composable
fun Dp.dpToPx() = with(LocalDensity.current) { this@dpToPx.toPx() }


@Composable
fun Int.pxToDp() = with(LocalDensity.current) { this@pxToDp.toDp() }

这可以让您直接将dp转换为px,反之亦然。
val dpValue = 16.dp
val pxConverted = dpValue.dpToPx()

val pxValue = 100
val dpConverted = pxValue.pxToDp()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接