Почему dp не работает на andorid TV так как ожидается?
В Android TV я с использую Jetpack Compose, где размер Card выглядит по-разному на телевизорах с разрешением 720p (эмулятор) и 1080p (эмулятор).
Card code:
...
Card(
modifier = Modifier
.width(412.dp)
.height(200.dp),
border = CardDefaults.border(border = Border.None),
colors = CardDefaults.colors(
containerColor = ColorTokens.grey_40,
contentColor = ColorTokens.white,
focusedContainerColor = Color.White,
focusedContentColor = Color.Black,
pressedContainerColor = Color.Gray,
pressedContentColor = Color.LightGray
),
shape = CardDefaults.shape (shape = RoundedCornerShape(CornerRadiusTokens.radius_300.withDPIOffset(LocalContext.current))),
onClick = { /*TODO*/ },
)
...
Я ожидал бы, что карточки будут выглядеть одинаково на обоих экранах, так как используется dp
. Что я упускаю из виду?
Ответы (1 шт):
Проблема в том, что наш дизайн был сделан для экрана с разрешением 1080p, и все значения элементов интерфейса указаны в пикселях (px), а не в dp. Это значит, что если попытаться использовать, скажем, 200px на разных экранах, то, очевидно, будет выглядеть по-разному.
Поэтому, чтобы поддерживать экраны 1080p и 720p, необходимо корректировать размеры с 1080 до 720 экранов.
Вот функция:
inline val Int.extToDp: Dp
@Composable get() = with(LocalDensity.current) { [email protected]() }
val Int.pxToDpWithOffset: Dp
@Composable get() {
val screenDensity: Float = LocalContext.current.resources.displayMetrics.densityDpi.toFloat()
val factor: Float = when {
screenDensity <= DisplayMetrics.DENSITY_TV -> {
(screenDensity / DisplayMetrics.DENSITY_XHIGH)
}
else /* DisplayMetrics.DENSITY_XHIGH */ -> {
1f
}
}
val adjustedDp: Int = (this * factor).roundToInt()
return adjustedDp.extToDp
}
Использование:
...
modifier = Modifier
.width(412.pxToDpWithOffset)
.height(200.pxToDpWithOffset)
...
Дайте знать если, что то пропустил:)