Разработка для экранов разных размеров


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

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

Создание адаптивных макетов с помощью Material Design 3

В макетах должны быть поля, заданные в процентах. В Wear Compose Material 3 ScreenScaffold автоматически рассчитывает процентные отступы и передает contentPadding в лямбда-выражение контента. Передайте этот параметр contentPadding в TransformingLazyColumn.

В следующем фрагменте кода используется компонент TransformingLazyColumn, чтобы создать контент, который будет отлично выглядеть на экранах Wear OS разных размеров:

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

В этом примере также показано, как использовать ScreenScaffold и AppScaffold. Они координируют работу приложения и отдельных экранов (маршрутов навигации), чтобы обеспечить правильную прокрутку и позиционирование TimeText.

Для верхнего и нижнего полей также обратите внимание на следующее:

  • Использование Modifier.minimumVerticalContentPadding (например, ListHeaderDefaults.minimumTopListContentPadding и ButtonDefaults.minimumVerticalListContentPadding), чтобы TransformingLazyColumn использовал по крайней мере рекомендуемые верхние и нижние отступы, когда эти элементы появляются на краю списка.
  • Использование ListHeader для первого элемента в списке вместо обычной composable-функции Text.

Полные спецификации можно найти в наборах дизайна Figma. Дополнительную информацию и примеры можно найти в следующих статьях:

  • Библиотека Horologist содержит вспомогательные инструменты для создания оптимизированных и дифференцированных приложений для Wear OS.
  • Пример ComposeStarter, демонстрирующий принципы, описанные в этом руководстве.
  • Пример JetCaster – более сложный пример создания приложения, которое работает с экранами разных размеров, с использованием библиотеки Horologist.

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

По умолчанию используйте макет с прокруткой, как показано выше. Это позволит пользователям взаимодействовать с компонентами приложения независимо от настроек экрана и размера дисплея устройства Wear OS.

Влияние разных размеров устройств и масштабирования шрифта

Влияние разных размеров устройств и масштабирования шрифта.

Диал. окна

Диалоговые окна также должны быть прокручиваемыми, если нет веской причины не делать этого. Компонент AlertDialog является адаптивным и по умолчанию поддерживает прокрутку, если контент не помещается в области просмотра.

Для специальных экранов могут требоваться макеты без прокрутки

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

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

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

На больших экранах можно разместить больше контента и функций. Чтобы реализовать такой дифференцированный подход, используйте контрольные точки размера экрана, показывая другой макет, когда размер экрана превышает 225 dp:

const val LARGE_DISPLAY_BREAKPOINT = 225

@Composable
fun isLargeDisplay() =
    LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT

// ...
// ... use in your Composables:
    if (isLargeDisplay()) {
        // Show additional content.
    } else {
        // Show content only for smaller displays.
    }
    // ...

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

Протестируйте сочетания размеров экрана и шрифта в режиме предварительного просмотра.

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

  • Как выглядят экраны при экстремальных размерах, например, самый большой шрифт в паре с самым маленьким экраном.
  • Как дифференцированный опыт ведет себя в контрольных точках.

Реализуйте предварительный просмотр с помощью WearPreviewDevices и WearPreviewFontScales для всех экранов приложения. Подробную информацию о настройке предварительного просмотра Wear OS, пользовательских спецификациях оборудования и предварительном просмотре прокручиваемых списков можно найти в статье Предварительный просмотр пользовательского интерфейса в Compose для Wear OS.

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun ComposeListPreview() {
    ComposeList()
}

Тестирование скриншотов

Тестирование скриншотов позволяет проверить, как приложение будет выглядеть на экранах разных размеров. Это особенно полезно, когда у вас нет доступа к таким устройствам, а на других экранах проблема не воспроизводится.

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

В наших примерах для тестирования скриншотов используется Roborazzi:

  1. Настройте файлы проекта и приложения build.gradle для использования Roborazzi.
  2. Создайте тест скриншотов для каждого экрана в приложении. Например, следующий код показывает тест скриншотов для экрана со списком:
@RunWith(ParameterizedRobolectricTestRunner::class)
class ComposeListScreenTest(
    override val device: WearDevice
) : WearScreenshotTest() {
    override val tolerance = 0.02f

    @Test
    fun myScreenTest() =
        runTest {
            AppScaffold {
                ComposeList()
            }
        }

    companion object {
        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters
        fun devices() = WearDevice.entries
    }
}

Важная информация

  • WearDevice.entries содержит определения для большинства популярных устройств Wear OS, поэтому тесты выполняются на репрезентативном диапазоне размеров экрана.

Как создать эталонные образы

Чтобы сгенерировать изображения для экранов, выполните в терминале следующую команду:

./gradlew recordRoborazziDebug

Проверьте изображения

Чтобы проверить изменения в существующих образах, выполните в терминале следующую команду:

./gradlew verifyRoborazziDebug

Полный пример тестирования скриншотов можно найти в примере ComposeStarter.