Я работаю над реализацией экрана для Android TV (Jetpack Compose), где (в частности) размер карты выглядит по-разному для (эмулятора) телевизора 720p и телевизора 1080p.
720:
1080:
Код карты:
...
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. Чего мне здесь не хватает?
@CommonsWare добавил ответ
@CommonsWare о, я понял, что вы имеете в виду, извините за путаницу. Похоже, размер телевизора эмулятора по умолчанию составляет 55". Однако в моем случае проблема заключалась в том (как я описал в своем ответе), что наш дизайн (в Figma) создан только для отображения 1080p, а размеры там в пикселях. Итак, если скажем Элемент пользовательского интерфейса (в дизайне) занимает 200 пикселей, я просто использовал это значение, как в dp, например - 200.dp, но использовать значение пикселя, как в dp, неправильно. Итак, я предлагаю решение (описанное ниже в ответе). ). Имеет ли это смысл?
@Sirop4ik: Лично я не до конца понимаю ваш ответ, но у меня была ошибка в предыдущем комментарии, который я сейчас удалил.
@CommonsWare в своем комментарии выше я имел в виду, что 200px != 200.dp
Наконец, у меня появилась идея: проблема в том, что наш дизайн был сделан для экрана 1080p со всеми значениями элементов пользовательского интерфейса в пикселях (а не в dp). Это означает, что если вы попытаетесь использовать, скажем, 200 пикселей для разных экранов, очевидно, что это будет выглядеть по-разному.
Итак, для поддержки экранов 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)
...
P.S.: Дайте мне знать, если вы видите какие-либо способы улучшения.
Каковы размеры эмулируемого экрана ваших двух изображений эмулятора? Я предполагаю, что вы обнаружите, что экран 1080p больше.