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


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

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

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

Макеты должны иметь поля, заданные в процентах . Поскольку Compose по умолчанию работает с абсолютными значениями, используйте rememberResponsiveColumnPadding из библиотеки Horologist для вычисления отступов и передайте их в параметр contentPadding объекта ScreenScaffold и параметр 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 .

Обратите внимание также на следующее относительно верхней и нижней обивки:

  • Указание первого и последнего ItemType для определения правильного отступа.
  • Для первого элемента списка используется ListHeader , поскольку 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.
    }
    // ...

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

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

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

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

Обязательно реализуйте предварительный просмотр с помощью WearPreviewDevices и WearPreviewFontScales для всех экранов вашего приложения.

@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 .