Освой Compose играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Обновлено 18.04.2024, 19 июня 2025
Аннотация @Preview позволяет задать внешний вид предварительного просмотра создаваемого приложения.
По умолчанию студия предлагает использовать аннотацию только с одним параметром @Preview(showBackground = true). На самом деле параметров гораздо больше. Её исходник выглядит следующим образом.
public constructor Preview(
val name: String = "",
val group: String = "",
@IntRange(from = 1.toLong()) val apiLevel: Int = -1,
val widthDp: Int = -1,
val heightDp: Int = -1,
val locale: String = "",
@FloatRange(from = 0.01.toDouble()) val fontScale: Float = 1f,
val showSystemUi: Boolean = false,
val showBackground: Boolean = false,
val backgroundColor: Long = 0,
@UiMode val uiMode: Int = 0,
@Device val device: String = Devices.DEFAULT,
@Wallpaper val wallpaper: Int = Wallpapers.NONE
)
Можно обойтись вообще без параметров. Ошибки не будет.
@Preview
@Composable
fun DefaultPreview() {
Content()
}
Если вы обратили внимание, то название у окна предварительного просмотра совпадает с именем функции DefaultPreview(). Вы можете задать своё имя через параметр name.
@Preview (name = "Можно всех кошечек посмотреть?")
По умолчанию элементы выводятся на прозрачный фон, что не всегда удобно. Можно добавить параметр showBackground - впрочем он уже и так у вас был изначально.
Но фон по умолчанию белый, а вам хочется другой? Хорошо, добавьте ещё один параметр backgroundColor.
@Preview(
name = "Можно всех кошечек посмотреть?",
showBackground = true,
backgroundColor = 0xCA7971
)

Можно задать размеры окна предварительного просмотра через widthDp и heightDp.
@Preview(
widthDp = 300,
heightDp = 400
)
А ещё можно группировать окна предварительного просмотра для разных компонентов в сложных проектах. Тогда можно будет переключаться между ними через меню или смотреть все элементы вместе.
@Preview(
name = "Просмотр котов",
showBackground = true,
group = "Коты"
)
@Composable
fun DefaultPreview() {
Text(text = "Привет, киска!")
}
@Preview(
name = "Cat Preview",
group = "Cats",
showBackground = true
)
@Composable
fun SecondPreview() {
Box {
Text(text = "Hello Kitty!")
}
}
Посмотрите два варианта, чтобы понять, как это работает.
А можно использовать сразу несколько аннотаций с разным набором параметров, чтобы видеть поведение макета в разных условиях.
@Preview(
name = "Можно всех кошечек посмотреть?",
showBackground = true,
showSystemUi = true
)
@Preview(
name = "Compact Preview",
widthDp = 300,
heightDp = 200
)
@Composable
fun DefaultPreview() {
Content()
}

Хочется увидеть, как компоненты будут смотреться на экране телефона? Добавьте параметр showSystemUi.
@Preview(
name = "Можно всех кошечек посмотреть?",
showSystemUi = true
)

Можно выбрать конкретный телефон из Pixel/Nexus через параметр device.
@Preview(
name = "Можно всех кошечек посмотреть?",
showSystemUi = true,
device = Devices.NEXUS_6P
)
Другие варианты.
@StringDef(
open = true,
value = [
Devices.DEFAULT,
Devices.NEXUS_7,
Devices.NEXUS_7_2013,
Devices.NEXUS_5,
Devices.NEXUS_6,
Devices.NEXUS_9,
Devices.NEXUS_10,
Devices.NEXUS_5X,
Devices.NEXUS_6P,
Devices.PIXEL_C,
Devices.PIXEL,
Devices.PIXEL_XL,
Devices.PIXEL_2,
Devices.PIXEL_2_XL,
Devices.PIXEL_3,
Devices.PIXEL_3_XL,
Devices.PIXEL_3A,
Devices.PIXEL_3A_XL,
Devices.PIXEL_4,
Devices.PIXEL_4_XL,
Devices.AUTOMOTIVE_1024p
]
)
Рассмотрим параметр uiMode. С его помощью можно, например, установить тёмную тему. Только не забудьте у текста поменять цвет шрифта, иначе будете искать чёрную кошку в чёрной комнате.
@Composable
fun Content() {
Text(
text = "Мурзик",
color = Color.White,
fontSize = 50.sp
)
}
@Preview(
name = "Можно всех кошечек посмотреть?",
showBackground = true,
showSystemUi = true,
uiMode = UI_MODE_NIGHT_YES
)
@Composable
fun DefaultPreview() {
Content()
}

Кроме UI_MODE_NIGHT_YES можно использовать множество других вариантов.
@IntDef(
value = [
UI_MODE_TYPE_MASK,
UI_MODE_TYPE_UNDEFINED,
UI_MODE_NIGHT_NO,
UI_MODE_NIGHT_YES,
UI_MODE_TYPE_APPLIANCE,
UI_MODE_TYPE_CAR,
UI_MODE_TYPE_DESK,
UI_MODE_TYPE_NORMAL,
UI_MODE_TYPE_TELEVISION,
UI_MODE_TYPE_VR_HEADSET,
UI_MODE_TYPE_WATCH,
UI_MODE_NIGHT_MASK,
UI_MODE_NIGHT_UNDEFINED,
UI_MODE_NIGHT_NO,
UI_MODE_NIGHT_YES
]
)
Позже появилась новая аннотация @PreviewLightDark.
Если приложение использует разные локали, например, строковые ресурсы на разных языках, то можно увидеть это на экране. Немного переделаем базовый пример. Также надо подготовить ресурсы в файле res/values-ru/strings.xml
@Composable
fun Greeting(name: String) {
Text(text = stringResource(id = R.string.hello) + " \$name!")
}
@Preview(showBackground = true, locale = "en")
@Preview(showBackground = true, locale = "ru")
@Composable
fun DefaultPreview() {
ComposeTheme {
Greeting(stringResource(id = R.string.barsik))
}
}

Параметр fontScale позволяет установить масштабирование шрифта от базового значения.
@Preview(fontScale = 2.00f, showBackground = true)
@Composable
fun DefaultPreview() {
ComposeTheme {
Greeting(stringResource(id = R.string.barsik))
}
}
Позже появилась аннотация @PreviewFontScale.
Можно установить динамические обои. Сам пока не использовал на практике.
@Preview(showBackground = true, wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE)
Если вам нужно протестировать, как будет выглядеть текстовая метка с разным количеством слов, то можно воспользоваться классом LoremIpsum.
@Preview(showBackground = true)
@Composable
fun ContentPreview() {
YourComposeTheme {
Text(text = LoremIpsum(words = 4)
.values
.toList()
.first()
.toString()
)
}
}
Вместо двух аннотаций для светлого и тёмного режимов, можно использовать родственную аннотацию @PreviewLightDark.
// Вместо
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun Preview() {
...
}
@PreviewLightDark
@Composable
fun Preview(){
YourComposeTheme {
Text(text = "Meow")
}
}
Если нужно протестировать сразу несколько размеров шрифта, то вместо многочисленных вызовов с параметром fontScale можно использовать аннотацию @PreviewFontScale.
// Вместо
@Preview(name = "85%", fontScale = 0.85f)
@Preview(name = "100%", fontScale = 1.0f)
@Preview(name = "115%", fontScale = 1.15f)
@Preview(name = "130%", fontScale = 1.3f)
@Preview(name = "150%", fontScale = 1.5f)
@Preview(name = "180%", fontScale = 1.8f)
@Preview(name = "200%", fontScale = 2f)
@Composable
private fun Preview() {
...
}
@PreviewFontScale
@Composable
fun Preview(){
YourComposeTheme {
Text(text = "Meow")
}
}
Сразу посмотреть на устройствах разных размеров можно через @PreviewScreenSizes.
// Вместо
@Preview(name = "Phone", device = PHONE, showSystemUi = true)
@Preview(name = "Phone - Landscape",
device = "spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420",
showSystemUi = true)
@Preview(name = "Unfolded Foldable", device = FOLDABLE, showSystemUi = true)
@Preview(name = "Tablet", device = TABLET, showSystemUi = true)
@Preview(name = "Desktop", device = DESKTOP, showSystemUi = true)
@Composable
private fun Preview() {
...
}
@PreviewScreenSizes
@Composable
fun Preview(){
YourComposeTheme {
Text(text = "Meow")
}
}