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


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

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

Как создавать адаптивные макеты с помощью Material Design 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.
    }
    // ...

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

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

Предварительный просмотр 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.