Поверхности в Jetpack Compose Glimmer

Поддерживаемые XR-устройства
Это руководство поможет вам создавать контент для таких устройств.
Очки

В Jetpack Compose Glimmer компонент surface – это основной строительный блок, который представляет собой отдельную визуальную область или физическую границу для таких компонентов, как кнопки и карточки.

Поверхность отвечает за следующие визуальные и физические свойства:

  • Обрезка. Обрезает дочерние элементы до указанной формы.
  • Граница. Добавляет внутреннюю границу, чтобы подчеркнуть границы компонента. Если фокус установлен, вокруг объекта будет нарисована более широкая рамка с подсветкой.
  • Фон. Применяет цвет фона к поверхности.
  • Эффекты глубины. Отрисовывает тени DepthEffect на основе состояния компонента (например, по умолчанию или при наведении фокуса).
  • Цвет контента. Задает цвет текста и значков на поверхности. По умолчанию рассчитывается на основе цвета фона.
  • Состояния взаимодействия. При нажатии на поверхность рисуется наложение, а при наведении фокуса – более широкая рамка с подсветкой.

Пример: создание поверхности

В приведенном ниже коде создается поверхность с обрезкой, фоном и границами по умолчанию:

@Composable
fun SurfaceSample() {
    Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) {
        Text("This is a surface")
    }
}

Взаимодействие и фокус

По умолчанию поверхности не фокусируются, поэтому пользователи не могут взаимодействовать с ними. В большинстве случаев поверхности должны быть интерактивными, чтобы пользователи могли перемещать фокус и переходить между элементами. Модификатор Compose focusable можно использовать для элементов, которые должны быть только доступны для выбора. Аналогичным образом можно создать кликабельную поверхность, используя модификатор Compose clickable. Вы также можете использовать другие модификаторы для поверхностей, требующих действий.

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

@Composable
fun FocusableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        modifier = Modifier
            .size(100.dp)
            .surface(interactionSource = interactionSource)
            .focusable(interactionSource = interactionSource),
        contentAlignment = Alignment.Center
    ) {
        Text("Focusable")
    }
}

@Composable
fun ClickableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        modifier = Modifier
            .size(100.dp)
            .surface(interactionSource = interactionSource)
            .focusable(interactionSource = interactionSource)
            .clickable(
                interactionSource = interactionSource,
                indication = null
            ) { /* Handle click action */ },
        contentAlignment = Alignment.Center
    ) {
        Text("Clickable")
    }
}

Ключевые моменты

  • Общий источник взаимодействия для объектов, на которые можно переходить. Поля .surface() и .focusable() должны иметь одинаковое значение interactionSource. Это позволяет поверхности реагировать на изменения фокуса.

  • Общий источник взаимодействия для интерактивных элементов. Параметры .surface() и .clickable() должны иметь одинаковое значение interactionSource. Это гарантирует, что визуальные состояния (например, нажатие или фокус) синхронизируются, позволяя поверхности визуально реагировать на ввод пользователя.

  • Порядок модификаторов. Последовательность модификаторов имеет решающее значение. Поскольку .surface() обрезает макет, размещение его до .clickable() гарантирует, что область прикосновения будет ограничена формой поверхности. Если .clickable() идет первым, область взаимодействия может выходить за видимые границы компонента.

SurfaceDepthEffect

Класс SurfaceDepthEffect управляет переходом теней между состояниями взаимодействия:

  • depthEffect – эффект тени, используемый, когда поверхность находится в состоянии по умолчанию.
  • focusedDepthEffect – эффект тени, используемый при фокусировке на поверхности.