dp と px と sp の相互変換。
Compose ではどうやるかという話。
👉 How to convert Dp to pixels in Android Jetpack Compose? - Stack Overflow
import androidx.compose.ui.platform.LocalDensity
val pxValue = with(LocalDensity.current) { 16.dp.toPx() }
// or
val pxValue = LocalDensity.current.run { 16.dp.toPx() }
Kotlin スコープ系の関数で取得できる、というのだが気持ちが悪い。
これは、以下でも同じ。
val pxValue = 16.dp.value * LocalDensity.current.density
少し、型を表示しながら少し試してみる。
with(LocalDensity.current) {
val dp1: Dp = 1.dp
val dp1ToPx: Float = dp1.toPx()
val dp1ToSp: TextUnit = dp1.toSp()
}
with(LocalDensity.current) {
val sp1: TextUnit = 1.sp
val sp1ToDp: Dp = sp1.toDp()
val sp1ToPx: Float = sp1.toPx()
}
Compose 側で、dp/px/sp の値の単位を以下に揃えようとしてるような雰囲気に見える。
dp → Dp
px → Float
sp → TextUnit
拡張関数にしてみる
そもそも、意味的に以下のような決まりがありました。
px = sp * scale
px = dp * density
→ sp * scale = dp * density
なので、単位を、それぞれの内部の value: Float に揃えて変換すると、
@Composable
internal fun Float.dpValueToPxValue(): Float {
return this * LocalDensity.current.density
}
@Composable
internal fun Float.dpValueToSpValue(): Float {
return this * LocalDensity.current.density / LocalDensity.current.fontScale
}
@Composable
internal fun Float.pxValueToDpValue(): Float {
return this / LocalDensity.current.density
}
@Composable
internal fun Float.pxValueToSpValue(): Float {
return this / LocalDensity.current.fontScale
}
@Composable
internal fun Float.spValueToDpValue(): Float {
return this * LocalDensity.current.fontScale / LocalDensity.current.density
}
@Composable
internal fun Float.spValueToPxValue(): Float {
return this * LocalDensity.current.fontScale
}
さらに、Compose の意向に添わせると、
どうなんですかね、ここらへん。