Разбивка модификаторов по фазам

Jetpack Compose выполняет модификаторы на разных этапах. В следующем разделе показано, к каким этапам относятся общие модификаторы и когда оцениваются их аргументы или лямбда-выражения.

Этап 1: Этап составления композиции

Эти модификаторы синхронно вычисляют аргументы внутри тела @Composable . Любое состояние, считанное здесь, регистрирует зависимость от области видимости `Composable restart` и запускает полную перекомпозицию при изменении.

  • Модификаторы статических размеров и габаритов :
    • Modifier.size(dp) , Modifier.width(dp) , Modifier.height(dp)
    • Modifier.fillMaxSize() , Modifier.fillMaxWidth() , Modifier.fillMaxHeight()
    • Modifier.wrapContentSize() , Modifier.wrapContentWidth() , Modifier.wrapContentHeight()
    • Modifier.requiredSize() , Modifier.defaultMinSize()
    • Modifier.aspectRatio(ratio)
    • Modifier.weight(weight) (в RowScope или ColumnScope )
    • Modifier.width(IntrinsicSize.Min / Max)
    • Modifier.height(IntrinsicSize.Min / Max)
  • Статическое расстояние и вставки :
    • Modifier.padding(all = dp) , Modifier.padding(start, top, end, bottom)
    • Modifier.windowInsetsPadding(insets) , Modifier.statusBarsPadding()
  • Прямые визуальные модификаторы значений :
    • Modifier.alpha(float) (считывает состояние во время композиции)
    • Modifier.rotate(degrees) (считывает состояние во время композиции)
    • Modifier.scale(scaleX, scaleY) (считывает состояние во время композиции)
    • Modifier.background(color = Color, shape = Shape)
    • Modifier.border(width, color, shape)
    • Modifier.shadow(elevation, shape)
    • Modifier.clip(shape)
    • Modifier.blur(radius)
  • Модификаторы статического положения :
    • Modifier.offset(x = dp, y = dp) (перегрузка прямого значения)
    • Modifier.absoluteOffset(x = dp, y = dp)
  • Динамические комбинируемые модификаторы :
    • Modifier.composed { ... } (запускает тело фабрики во время композиции)

Этап 2: Этап компоновки

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

Шаг 2А: Измерение

Определяет размер ( width , height ) и ограничения. Состояние, считанное здесь, запускает повторное измерение и замену:

  • Modifier.layout { measurable, constraints -> ... } : Код, выполняемый перед layout(w, h) во время измерения.

Шаг 2B: Обратные вызовы для размещения и компоновки

Определяет координаты (x, y) . Считывание состояния здесь запускает только замену (пропуская измерение и композицию):

  • Modifier.offset { IntOffset(x, y) } (перегрузка лямбда-функции)
  • Modifier.absoluteOffset { IntOffset(x, y) } (перегрузка лямбда-функции)
  • Modifier.layout { ... layout(w, h) { placeable.place(x, y) } } : Код внутри блока layout(w, h) { ... } .
  • Modifier.onPlaced { layoutCoordinates -> ... } : Вызывается после определения координат родительского элемента во время размещения.
  • Modifier.onSizeChanged { intSize -> ... } : Вызывается после завершения измерения макета, если размер изменился.
  • Modifier.onGloballyPositioned { layoutCoordinates -> ... } : Вызывается после завершения всего этапа компоновки окна.

Этап 3: Этап чертежей

Эти модификаторы выполняются во время отрисовки холста. Считывание состояния внутри этих блоков пропускает как композицию, так и компоновку , выполняя только проход отрисовки:

  • Modifier.graphicsLayer { ... } :
    • Свойства, обновленные в лямбда-функции: alpha , translationX , translationY , scaleX , scaleY , rotationX , rotationY , rotationZ , shadowElevation , shape , clip , renderEffect , transformOrigin .
  • Modifier.drawBehind { ... } :
    • Отображает элементы управления на холсте за содержимым, которое можно комбинировать.
  • Modifier.drawWithContent { ... } :
    • Управляет порядком отрисовки с помощью drawContent() .
  • Modifier.drawWithCache { ... } :
    • Внешний блок выполняется при изменении размера или компоновки для кэширования объектов Path , Paint или Brush ; onDrawBehind или onDrawWithContent выполняются при каждой отрисовке кадра.

Вне цикла рекомпозиции — модификаторы наблюдения

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

Семантика и доступность

Обрабатывает семантические свойства для служб обеспечения доступности (TalkBack) и тестирования:

  • Modifier.semantics { ... }
  • Modifier.clearAndSetSemantics { ... }

Ввод, жесты и события

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

  • Modifier.pointerInput(key) { detectTapGestures { ... } } / detectDragGestures / awaitPointerEventScope
  • Modifier.clickable(enabled, onClickLabel) { ... }
  • Modifier.combinedClickable { ... }
  • Modifier.toggleable { ... }
  • Modifier.selectable { ... }
  • Modifier.draggable(...) / Modifier.scrollable(...) / Modifier.draggable2D(...)
  • Modifier.onFocusChanged { focusState -> ... }
  • Modifier.onKeyEvent { keyEvent -> ... }
  • Modifier.onVisibilityChanged { isVisible -> ... } : Функция обратного вызова вызывается, когда видимость составного элемента изменяется после заданной задержки в сопрограмме.

Краткий справочник: Фаза значения и фаза лямбда

При чтении значения состояния в лямбда-функции чтение откладывается на более поздний этап, который пропускает предыдущие этапы при изменении этого состояния:

Модификатор / Шаблон Прямая стоимость (состав) Вариант лямбда (отложенная фаза) Когда меняется состояние
Компенсировать Modifier.offset(x, y) Modifier.offset { IntOffset(x, y) } Макет (Размещение) (Пропускает композицию)
Альфа-канал / Непрозрачность Modifier.alpha(alpha) Modifier.graphicsLayer { this.alpha = alpha } Рисунок (пропускает композицию и компоновку)
Вращение Modifier.rotate(degrees) Modifier.graphicsLayer { rotationZ = degrees } Рисунок (пропускает композицию и компоновку)
Шкала Modifier.scale(scale) Modifier.graphicsLayer { scaleX = s; scaleY = s } Рисунок (пропускает композицию и компоновку)
Перевод Modifier.padding(...) Modifier.graphicsLayer { translationX = ... } Рисунок (пропускает композицию и компоновку)
Цвет фона Modifier.background(color) Modifier.drawBehind { drawRect(color) } Рисунок (пропускает композицию и компоновку)
Прокрутка / Параллакс Modifier.offset(scroll.dp) Modifier.offset { IntOffset(0, scroll) } Макет (Размещение) (Пропускает композицию)

Сопоставление интерфейса Modifier.Node

Для пользовательских модификаторов, использующих высокопроизводительный API Modifier.Node , этапы напрямую сопоставляются с интерфейсами возможностей узла:

Фаза Интерфейс Modifier.Node Основные методы
Разметка (измерение и размещение) LayoutModifierNode measure(measurable, constraints)
Схема (глобальные координаты) GlobalPositionAwareModifierNode onGloballyPositioned(coordinates)
Макет (Размещение) LayoutAwareModifierNode onRemeasured(size) , onPlaced(coordinates)
Рисунок DrawModifierNode draw(ContentDrawScope)
Ввод / Указатель PointerInputModifierNode onPointerEvent(...) , onCancelPointerInput()
Семантика SemanticsModifierNode applySemantics(SemanticsPropertyReceiver)
Фокус FocusEventModifierNode onFocusEvent(focusState)