Предварительный просмотр интерфейса с помощью составных макетов

Composable-функция определяется с помощью функции и аннотации @Composable:

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

Простой текстовый элемент, содержащий слова "Hello
World"

Чтобы включить предварительный просмотр этой composable-функции, создайте другую composable-функцию с аннотациями @Composable и @Preview. Новый аннотированный компонент теперь содержит компонент, который вы создали изначально, SimpleComposable:

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

Аннотация @Preview указывает Android Studio, что эта composable-функция должна быть показана в представлении дизайна этого файла. Вы можете видеть, как меняется предварительная версия composable-функции по мере того, как вы вносите изменения.

GIF-изображение, на котором показано обновление в реальном времени с помощью Compose Preview

Вы можете добавить параметры в код вручную, чтобы настроить способ отрисовки @Preview в Android Studio. Вы даже можете добавить аннотацию @Preview к одной и той же функции несколько раз, чтобы посмотреть, как будет выглядеть composable-функция с разными свойствами.

Одно из главных преимуществ использования @Preview-функций – возможность не полагаться на эмулятор в Android Studio. Вы можете сохранить ресурсоемкий запуск эмулятора для более окончательных изменений внешнего вида и использовать @Preview для внесения и тестирования небольших изменений кода.

Чтобы эффективно использовать аннотацию @Preview, определите экраны с точки зрения состояния, которое они получают на входе, и событий, которые они выводят.

Определите @Preview

В Android Studio есть функции, позволяющие расширить возможности предварительного просмотра. Вы можете изменить дизайн контейнера, взаимодействовать с ними или развернуть их непосредственно на эмуляторе или устройстве.

Размеры

По умолчанию размеры @Preview выбираются автоматически, чтобы контент поместился в контейнер. Чтобы задать размеры вручную, добавьте параметры heightDp и widthDp. Эти значения уже интерпретируются как dp, поэтому добавлять к ним .dp не нужно:

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

Желтый квадрат с текстом "Hello
World"

Предпросмотр динамической цветовой темы

Если в вашем приложении включена функция динамических цветов, используйте атрибут wallpaper, чтобы менять обои и смотреть, как интерфейс реагирует на разные обои, выбранные пользователями. Выберите одну из тем обоев, предложенных в курсе Wallpaper. Для этой функции требуется Compose 1.4.0 или более поздней версии.

Как использовать на разных устройствах

В Android Studio Flamingo можно изменить параметр device аннотации Preview, чтобы задать конфигурации для композиций на разных устройствах.

Пример composable-функции

Если параметр device имеет пустую строку (@Preview(device = "")), вы можете вызвать автозаполнение, нажав Ctrl + Space. Затем вы можете задать значения каждого параметра.

Как изменить функцию sample

В списке автозаполнения выберите устройство, например @Preview(device = "id:pixel_4"). Вы также можете ввести данные устройства вручную, нажав spec:width=px,height=px,dpi=int… и указав значения каждого параметра.

Спецификация
списка

Чтобы применить изменения, нажмите Enter. Чтобы отменить, нажмите Esc.

Если вы зададите недопустимое значение, объявление будет подчеркнуто красным, и может быть доступно исправление (Alt + Enter (⌥ + ⏎ для macOS) > Заменить на…. Инструмент проверки попытается предложить исправление, максимально похожее на ваш ввод.

Пример недопустимого значения

Региональные настройки

Чтобы протестировать разные языковые стандарты, добавьте параметр locale:

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

Простой текстовый элемент со словом "Bonjour" и французским флагом

Выбрать цвет фона

По умолчанию фон composable-функции прозрачный. Чтобы добавить фон, добавьте параметры showBackground и backgroundColor. Помните, что backgroundColor – это ARGB-код Long, а не значение Color:

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

Зеленый прямоугольник с текстом "Hello
World"

Интерфейс системы

Если вам нужно, чтобы в окне предпросмотра показывались строки статуса и действий, добавьте параметр showSystemUi:

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

Окно предпросмотра, в котором показано действие со строками статуса и действий.

Режим интерфейса

Параметр uiMode может принимать любые Configuration.UI_*константы и позволяет изменять поведение предварительной версии. Например, вы можете включить ночной режим, чтобы посмотреть, как изменится тема.

Интерфейс предварительного просмотра

LocalInspectionMode

Вы можете прочитать из LocalInspectionMode CompositionLocal, чтобы узнать, отрисовывается ли компонуемый элемент в предварительном просмотре (внутри проверяемого компонента). Если композиция отрисовывается в режиме предварительного просмотра, значением LocalInspectionMode.current будет true. Эта информация позволяет настраивать предварительный просмотр. Например, вместо реальных данных в окне предпросмотра можно показывать изображение-заполнитель.

Таким образом можно обойти ограничения. Например, показывать примеры данных вместо сетевых запросов.

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

Как взаимодействовать с устройством @Preview

Android Studio предлагает функции, которые позволяют взаимодействовать с созданными вами предварительными версиями. Это взаимодействие помогает понять, как будет работать предпросмотр, и упрощает навигацию по интерфейсу.

Интерактивный режим

В интерактивном режиме с предварительной версией можно взаимодействовать так же, как с приложением на телефоне или планшете. Интерактивный режим изолирован в среде песочницы (то есть от других предварительных просмотров), где вы можете нажимать на элементы и вводить пользовательские данные в предварительном просмотре. Это быстрый способ проверить различные состояния, жесты и даже анимацию вашей composable-функции.

Пользователь нажимает кнопку "Интерактивный" в предварительном просмотре.

Видео, на котором пользователь взаимодействует с предпросмотром.

Навигация по коду и составляемые структуры

Чтобы посмотреть контуры композиций, содержащихся в окне предварительного просмотра, наведите на него указатель. При нажатии на контур composable-функции редактор переходит к ее определению.

Пользователь наводит курсор на предварительный просмотр, и Studio показывает контуры его композиций.

Запустить предпросмотр

Вы можете запустить определенный @Preview на эмуляторе или физическом устройстве. Предварительная версия развертывается в том же приложении проекта, что и новый Activity, поэтому у нее те же контекст и разрешения. Вам не нужно писать шаблонный код для запроса разрешения, если оно уже предоставлено.

Нажмите на значок Запустить предварительный просмотр Запустить просмотр
icon рядом с аннотацией @Preview или вверху окна предварительного просмотра. Android Studio развернет аннотацию @Preview на подключенном устройстве или эмуляторе.

пользователь нажимает на предварительный просмотр;

Видео, на котором пользователь развертывает предварительную версию на устройстве

Копировать @Preview

Каждый предварительный просмотр можно скопировать как изображение, нажав на него правой кнопкой мыши.

Пользователь нажимает на предпросмотр, чтобы скопировать его как изображение.

Несколько предварительных просмотров одной и той же аннотации @Preview

Вы можете показывать несколько версий одной и той же @Preview composable-функции с разными спецификациями или параметрами. Это позволит сократить объем шаблонного кода, который вам пришлось бы написать в противном случае.

Шаблоны для мультипредпросмотра

В версии androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01+ представлены шаблоны API Multipreview: @PreviewScreenSizes, @PreviewFontScales, @PreviewLightDark и @PreviewDynamicColors. Благодаря этому с помощью одной аннотации можно просматривать интерфейс Compose в распространенных сценариях.

Предварительный просмотр разных шрифтов и размеров экрана с помощью шаблонов.

Как создавать собственные аннотации для мультипредпросмотра

С помощью функции "Несколько вариантов предпросмотра" можно задать класс аннотаций, который сам содержит несколько аннотаций @Preview с разными конфигурациями. Если добавить эту аннотацию в composable-функцию, все варианты предпросмотра будут автоматически отрисованы одновременно. Например, с помощью этой аннотации можно одновременно просматривать несколько устройств, размеров шрифта или тем, не повторяя эти определения для каждой отдельной composable-функции.

Для начала создайте собственный класс аннотаций:

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

Вы можете использовать эту специальную аннотацию для предварительного просмотра композиций:

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

Вкладка "Дизайн" в Android Studio, на которой показан компонуемый элемент с маленьким и большим шрифтом

Вы можете комбинировать аннотации для нескольких предпросмотров и обычных предпросмотров, чтобы создать более полный набор предпросмотров. Если вы добавите несколько аннотаций, это не значит, что будут показаны все возможные комбинации. Вместо этого каждая аннотация для нескольких вариантов предпросмотра работает независимо и отображает только свои варианты.

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

Вкладка "Дизайн" в Android Studio, на которой показан компонент во всех конфигурациях

Благодаря возможности комбинировать разные варианты предпросмотра (как обычного, так и многократного) вы можете более тщательно тестировать различные свойства крупных проектов.

@Preview и большие наборы данных

Часто возникает необходимость передать большой набор данных в компонуемый предварительный просмотр. Для этого просто передайте образцы данных в Composable-функцию предварительного просмотра, добавив параметр с аннотацией @PreviewParameter.

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

Чтобы предоставить образец данных, создайте класс, который реализует PreviewParameterProvider и возвращает образец данных в виде последовательности.

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

В результате для каждого элемента данных в последовательности будет создан один предварительный просмотр:

Предварительный просмотр композиций Elise, Frank и Julia

Один и тот же класс поставщика можно использовать для нескольких предварительных просмотров. При необходимости ограничьте количество предпросмотров, задав параметр limit.

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

По умолчанию в предварительных просмотрах с использованием @PreviewParameter названия формируются на основе индекса параметра и названия свойства (user 0, user 1, user 2 и т. д.), поэтому их сложно различать. Чтобы улучшить качество предварительного просмотра, вы можете задать для каждого из них собственные названия, переопределив getDisplayName() в PreviewParameterProvider. Это помогает различать разные варианты данных или состояния интерфейса. Например, вы можете присвоить ярлыки на основе входных данных:

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

Предварительный просмотр со специальными медийными креативами, показывающими composable-функции Elise - 30, Frank - 31 и Julia - 40

Создание предпросмотра с помощью ИИ

ИИ-агент в Android Studio может автоматически создавать предварительные версии Compose для ваших composable-функций. Нажмите правой кнопкой мыши на composable-функцию и выберите ИИ > Создать предварительный просмотр для [название composable-функции]. Агент анализирует вашу composable-функцию и создает необходимый @Preview шаблон с правильными параметрами, чтобы вы могли быстро проверить, правильно ли отображается интерфейс.

Создайте предварительный просмотр письма с помощью ИИ.

Класс аннотаций @Preview

Чтобы посмотреть полный список параметров, которые можно настроить при создании предварительного просмотра, нажмите Ctrl или ⌘ и выберите аннотацию @Preview в Android Studio.

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) 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,
)

Ограничения и рекомендации

Android Studio выполняет код предварительного просмотра непосредственно в области предварительного просмотра. Для этого не нужно запускать эмулятор или физическое устройство, поскольку используется портированная часть фреймворка Android под названием Layoutlib. Layoutlib – это специальная версия фреймворка Android, предназначенная для работы на устройствах, отличных от Android. Цель библиотеки – обеспечить предварительный просмотр макета в Android Studio, который будет максимально похож на то, как он будет выглядеть на устройствах.

Ограничения предварительного просмотра

Поскольку в Android Studio предварительный просмотр выполняется без использования всего фреймворка Android, он не требует больших ресурсов. Однако при этом действуют следующие ограничения:

  • Нет доступа к сети
  • Нет доступа к файлам
  • Некоторые API Context могут быть доступны не полностью.

Предпросмотр и ViewModels

При использовании ViewModel в рамках composable-функции предварительный просмотр ограничен. Система предварительного просмотра не может создать все параметры, передаваемые в ViewModel, например репозитории, варианты использования, менеджеры и т. п. Кроме того, если ваш элемент ViewModel участвует в инъекции зависимостей (например, с помощью Hilt), система предварительного просмотра не сможет создать весь граф зависимостей, чтобы сконструировать ViewModel.

При попытке предварительного просмотра composable-функции с помощью ViewModel Android Studio показывает ошибку при отрисовке этой composable-функции:

Панель проблем в Android Studio с сообщением &quot;Не удалось создать экземпляр ViewModel&quot;

Если вы хотите посмотреть, как выглядит composable-функция, в которой используется ViewModel, создайте другую composable-функцию с параметрами из ViewModel, переданными в качестве аргументов composable-функции. В этом случае вам не нужно просматривать composable-функцию, в которой используется ViewModel.

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

Дополнительные ресурсы

  • Чтобы узнать больше о том, как Android Studio помогает @Preview, и получить дополнительные советы по использованию инструментов, ознакомьтесь с блогом Compose Tooling.
  • Информацию о том, как работать с устаревшими представлениями, можно найти в статье Как создать макет с помощью представлений.