Кастомизация

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

Дополнительная логика описывается в обработчике расширения DivExtensionHandler.

Готовые расширения

Идентификатор

Описание

Исходный код

pinch-to-zoom

Увеличивает элемент.

Android
iOS

lottie

Подключает Lottie-анимации к gif-image.

Android
iOS
Web

input_autocorrection

Управляет автокоррекцией текста в элементах input (только для iOS).

iOS

rasterize

Исправляет проблемы с отрисовкой вне экрана в overlap контейнерах (только для iOS).

iOS

blur

Добавляет эффект размытия к элементу (только для iOS).

iOS

liquid_glass

Добавляет эффект Liquid Glass к элементу (только для iOS 26 и новее).

iOS

backdrop-effect

Применяет сложные графические эффекты к фону элемента: размытие, преломление, коррекцию цвета и подсветку краев (только для Android).

Android

Подключение

Примечание

В качестве примера в этом разделе используется расширение Lottie.

build.gradle

dependencies {
    implementation "com.yandex.div:div-pinch-to-zoom:${versions.divkit}"
    implementation "com.airbnb.android:lottie:${versions.lottie}"
    implementation "com.yandex.div:div-lottie:${versions.lottie}"
}

В коде:

val pinchToZoomConfiguration = DivPinchToZoomConfiguration.Builder(this)
    .host(window)
    .dimColor(0xFF808080.toInt())
    .build()
val rawResProvider = object : DivLottieRawResProvider {
    override fun provideRes(url: String): Int? {
        if (url == "res://love") return R.raw.love_anim
        return null
    }
    override fun provideAssetFile(url: String): String? {
        if (url == "asset://banana") return "lottie/lottie_1.json"
        return null
    }
}
val divConfiguration = DivConfiguration.Builder(DefaultDivImageLoader(Container.imageManager))
    .experimentConfig(experimentConfig)
    .actionHandler(actionHandler)
    .divLogger(logger)
    .extension(DivPinchToZoomExtensionHandler(pinchToZoomConfiguration))
    .extension(DivLottieExtensionHandler(rawResProvider))
    .build()
val divContext = DivContext(baseContext = this, configuration = divConfiguration)
divView = DivView(divContext)

Обработчики расширений должны соответствовать протоколу DivExtensionHandler.

Для подключения обработчика передайте его в DivBlockModelingContext:

DivBlockModelingContext(
  ...
  extensionHandlers: [
    PinchToZoomExtensionHandler(overlayView: rootView),
    SomeExtensionHandler()
  ]
)
import { lottieExtensionBuilder } from '@divkitframework/divkit/client';
import Lottie from 'lottie-web/build/player/lottie';

const map = new Map();

map.set('lottie', lottieExtensionBuilder(Lottie.loadAnimation));

render({
    id: 'test',
    target: element,
    json: {},
    extensions: map
});

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

Lottie в анимированном gif-изображении

Для подключения анимации к gif-изображению заполните массив extensions:

{
  "extensions": [
    {
      "id": "lottie",
      "params": {
        "lottie_url": "https://assets9.lottiefiles.com/packages/lf20_edpg3c3s.json",
        "repeat_count": 3,
        "repeat_mode": "restart"
      }
    }
  ]
}

Примечание

Поведение параметра repeat_count

  • repeat_count: 0 — анимация проигрывается один раз
  • repeat_count: 1 — анимация проигрывается два раза
  • repeat_count: N — анимация проигрывается N+1 раз
  • repeat_count: -1 — бесконечное зацикливание

Параметры

Описание

id

Идентификатор расширения.

lottie_url

Обязательная ссылка на Lottie JSON, если не задан параметр lottie_json. Может работать по схемам asset:*{address} или res:*{address} для встроенных ресурсов. Связывание ресурсов по этим схемам происходит через зависимость DivLottieRawResProvider, которая передается в DivLottieExtensionHandler.

При использовании неподдерживаемых схем URL (не http/https/file/res) предзагрузка анимации будет пропущена с записью ошибки в лог.

lottie_json

Обязательный параметр, если не задана ссылка lottie_url. Содержит Lottie JSON.

repeat_count

Количество повторов анимации. Для бесконечного количества повторов используйте значение -1.

repeat_mode

Действие после окончания анимации. Может принимать значения:

  • restart — анимация начинается сначала;
  • reverse — анимация идет покадрово в обратном порядке.

min_frame

Минимальный кадр, с которого начинается анимация. Используется для сложных сценариев цикличного воспроизведения.

is_playing

Управляет автоматическим воспроизведением анимации при инициализации. Если установлено значение false, анимация не будет запускаться автоматически. По умолчанию: true.

Управление автокоррекцией текста

Для управления автокоррекцией текста в элементах input на iOS используйте расширение input_autocorrection:

{
  "extensions": [
    {
      "id": "input_autocorrection",
      "params": {
        "enabled": false
      }
    }
  ]
}

Параметры

Описание

id

Идентификатор расширения.

enabled

Управляет включением автокоррекции для поля ввода. Установите значение false, чтобы отключить автокоррекцию.

Автоматическая коррекция соотношения сторон изображений

Для автоматического кадрирования изображений в div-image до ожидаемого соотношения сторон используйте расширение aspect-correction (только для iOS):

{
  "extensions": [
    {
      "id": "aspect-correction",
      "params": {
        "aspect_tolerance": 0.001
      }
    }
  ]
}

Параметры

Описание

id

Идентификатор расширения.

aspect_tolerance

Допуск отклонения соотношения сторон (опционально). Если фактическое соотношение сторон отличается от ожидаемого менее чем на это значение, кадрирование не применяется. По умолчанию: 0.001.

Особенности работы:

  • Изображения кадрируются центрально при значительном отклонении от ожидаемого соотношения сторон
  • Если фактическое соотношение сторон меньше ожидаемого - обрезается по высоте
  • Если фактическое соотношение сторон больше ожидаемого - обрезается по ширине
  • Поддерживается кэширование обработанных изображений для оптимизации производительности

Интеграция на iOS:

DivBlockModelingContext(
  ...
  extensionHandlers: [
    AspectCorrectionExtensionHandler(aspectTolerance: 0.001)
  ]
)

Растеризация для исправления отрисовки вне экрана

Для исправления проблем с отрисовкой вне экрана в overlap контейнерах используйте расширение rasterize (только для iOS):

{
  "extensions": [
    {
      "id": "rasterize"
    }
  ]
}

Параметры

Описание

id

Идентификатор расширения.

Особенности работы:

  • Применяет растеризацию к блокам через layer.shouldRasterize = true
  • Использует UIScreen.main.scale для оптимального качества
  • Решает проблемы с отрисовкой вне экрана в overlap контейнерах

Интеграция на iOS:

DivBlockModelingContext(
  ...
  extensionHandlers: [
    RasterizeExtensionHandler()
  ]
)

Эффект размытия

Для добавления эффекта размытия к элементу используйте расширение blur (только для iOS):

Пример
{
  "extensions": [
    {
      "id": "blur",
      "params": {
        "intensity": 0.5
      }
    }
  ]
}

Укажите ровно один из параметров: style или intensity. Если заданы оба параметра или не задан ни
один, DivKit сообщает об ошибке построения блока и не применяет размытие.

Параметры

Описание

id

Идентификатор расширения.

style

Стиль эффекта размытия с полной системной интенсивностью. Параметр нельзя использовать вместе с
intensity. Доступные значения:

  • extra_light — очень светлый
  • regular — обычный
  • prominent — выразительный
  • system_ultra_thin_material — ультратонкий материал
  • system_ultra_thin_material_light — ультратонкий материал (светлый вариант)
  • system_ultra_thin_material_dark — ультратонкий материал (темный вариант)
  • system_thin_material — тонкий материал
  • system_thin_material_light — тонкий материал (светлый вариант)
  • system_thin_material_dark — тонкий материал (темный вариант)
  • system_material — материал
  • system_material_light — материал (светлый вариант)
  • system_material_dark — материал (темный вариант)
  • system_thick_material — толстый материал
  • system_thick_material_light — толстый материал (светлый вариант)
  • system_thick_material_dark — толстый материал (темный вариант)
  • system_chrome_material — хром материал
  • system_chrome_material_light — хром материал (светлый вариант)
  • system_chrome_material_dark — хром материал (темный вариант)

intensity

Интенсивность обычного системного blur в диапазоне 0...1. Значения за пределами диапазона
ограничиваются. Параметр нельзя использовать вместе с style. Он управляет интерполяцией между
отсутствием размытия и обычным системным blur, а не радиусом размытия. Поддерживает выражения.

Особенности работы:

  • Использует системные blur-эффекты iOS (UIBlurEffect)
  • Поддерживает либо системный стиль с полной интенсивностью, либо настройку интенсивности обычного
    blur через интерполяцию UIKit-эффекта
  • Поддерживает как базовые стили, так и material-стили с вариантами для светлой и темной темы
  • Применяется ко всему элементу, к которому добавлено расширение

Интеграция на iOS:

DivBlockModelingContext(
  ...
  extensionHandlers: [
    BlurExtensionHandler()
  ]
)

Эффект Liquid Glass

Чтобы добавить эффект Liquid Glass к элементу, используйте расширение liquid_glass (только для iOS):

{
  "extensions": [
    {
      "id": "liquid_glass",
      "params": {
        "style": "regular",
        "is_interactive": true,
        "tint_color": "#80FF1744",
        "corner_style": {
          "type": "capsule",
          "max_radius": 16
        },
        "ui_style_variable": "ui_style"
      }
    }
  ]
}

Расширение работает на iOS 26 и новее. На более ранних версиях элемент отрисовывается без эффекта, лэйаут при этом не меняется.

Параметры

Описание

id

Идентификатор расширения.

is_enabled

Включает эффект. Если задано значение false, элемент отрисовывается без него, размеры и положение элемента не меняются. Удобно для переключения эффекта выражением. По умолчанию: true.

style

Обязательный параметр. Стиль эффекта. Доступные значения:

  • regular — обычное стекло;
  • clear — прозрачное стекло.

is_interactive

Включает интерактивное поведение эффекта: стекло реагирует на нажатие. Опциональный параметр.

tint_color

Цвет подсветки эффекта. Опциональный параметр.

corner_style

Скругление углов эффекта. Опциональный параметр. Если не задан, используется скругление, выбранное системой. Доступные значения параметра type:

  • capsule — углы скругляются в капсулу пропорционально размеру элемента. Необязательный параметр max_radius ограничивает радиус сверху;
  • corners — фиксированные радиусы, задаются необязательными параметрами top_left, top_right, bottom_left и bottom_right. Незаданный угол не скругляется.

ui_style_variable

Имя переменной, в которую записывается light или dark. Опциональный параметр. Эффект сам определяет стиль оформления по контенту под собой, поэтому этот стиль может отличаться от стиля карточки. Используйте переменную, чтобы подобрать под него цвет контента поверх стекла.

Особенности работы:

  • Элемент оборачивается в UIVisualEffectView с UIGlassEffect, поэтому фон самого элемента отрисовывается поверх эффекта — не задавайте элементу непрозрачный background.
  • Все параметры поддерживают выражения, в том числе is_enabled и style.
  • Если style не задан или содержит недопустимое значение, DivKit сообщает об ошибке построения блока и не применяет эффект.

Интеграция на iOS:

DivBlockModelingContext(
  ...
  extensionHandlers: [
    LiquidGlassExtensionHandler()
  ]
)

Пример:

Карточка с несколькими вариантами эффекта
{
  "templates": {
    "glass_label": {
      "type": "text",
      "font_size": 15,
      "font_weight": "medium",
      "text_alignment_horizontal": "center",
      "text_color": "#FFFFFFFF",
      "width": {
        "type": "match_parent"
      }
    }
  },
  "card": {
    "log_id": "liquid_glass_sample",
    "variables": [
      {
        "name": "is_enabled",
        "type": "boolean",
        "value": true
      },
      {
        "name": "ui_style",
        "type": "string",
        "value": "unknown"
      }
    ],
    "states": [
      {
        "state_id": 0,
        "div": {
          "type": "container",
          "orientation": "vertical",
          "height": {
            "type": "match_parent"
          },
          "paddings": {
            "left": 16,
            "right": 16,
            "top": 24,
            "bottom": 24
          },
          "background": [
            {
              "type": "gradient",
              "angle": 45,
              "colors": [
                "#FFFF3D00",
                "#FF00E676",
                "#FF2979FF"
              ]
            }
          ],
          "items": [
            {
              "type": "container",
              "orientation": "vertical",
              "content_alignment_vertical": "center",
              "height": {
                "type": "fixed",
                "value": 56
              },
              "margins": {
                "bottom": 16
              },
              "paddings": {
                "left": 20,
                "right": 20
              },
              "items": [
                {
                  "type": "glass_label",
                  "text": "clear + tint_color"
                }
              ],
              "extensions": [
                {
                  "id": "liquid_glass",
                  "params": {
                    "style": "clear",
                    "tint_color": "#80FF1744",
                    "corner_style": {
                      "type": "capsule",
                      "max_radius": 16
                    }
                  }
                }
              ]
            },
            {
              "type": "container",
              "orientation": "vertical",
              "content_alignment_vertical": "center",
              "height": {
                "type": "fixed",
                "value": 56
              },
              "margins": {
                "bottom": 16
              },
              "paddings": {
                "left": 20,
                "right": 20
              },
              "items": [
                {
                  "type": "glass_label",
                  "text": "is_enabled = @{is_enabled}"
                }
              ],
              "extensions": [
                {
                  "id": "liquid_glass",
                  "params": {
                    "style": "regular",
                    "is_enabled": "@{is_enabled}",
                    "corner_style": {
                      "type": "corners",
                      "top_left": 4,
                      "top_right": 24,
                      "bottom_left": 24,
                      "bottom_right": 4
                    }
                  }
                }
              ]
            },
            {
              "type": "container",
              "orientation": "vertical",
              "paddings": {
                "left": 16,
                "right": 16,
                "top": 16,
                "bottom": 16
              },
              "border": {
                "corner_radius": 16
              },
              "background": [
                {
                  "type": "solid",
                  "color": "#FF101010"
                }
              ],
              "items": [
                {
                  "type": "container",
                  "orientation": "vertical",
                  "content_alignment_vertical": "center",
                  "height": {
                    "type": "fixed",
                    "value": 56
                  },
                  "paddings": {
                    "left": 20,
                    "right": 20
                  },
                  "items": [
                    {
                      "type": "glass_label",
                      "text": "over dark content"
                    }
                  ],
                  "extensions": [
                    {
                      "id": "liquid_glass",
                      "params": {
                        "style": "regular",
                        "ui_style_variable": "ui_style",
                        "corner_style": {
                          "type": "capsule"
                        }
                      }
                    }
                  ]
                },
                {
                  "type": "text",
                  "text": "ui_style = @{ui_style}",
                  "font_size": 13,
                  "text_color": "#FFFFFFFF",
                  "margins": {
                    "top": 8
                  }
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Эффекты фона

Для применения графических эффектов к фону элемента используйте расширение backdrop-effect (только для Android):

{
  "extensions": [
    {
      "id": "backdrop-effect",
      "params": {
        "blur_radius": 10.0,
        "refraction_height": 5.0,
        "refraction_strength": 0.5,
        "chromatic_aberration": 0.3,
        "brightness": 1.2,
        "contrast": 1.1,
        "saturation": 0.9,
        "rim_highlight_angle": 45.0,
        "rim_highlight_fade": 0.5,
        "corner_radius": 16.0,
        "backdrop_scope": "card"
      }
    }
  ]
}

Параметры

Описание

id

Идентификатор расширения.

blur_radius

Радиус размытия фона в пикселях. Опциональный параметр.

refraction_height

Высота эффекта преломления. Опциональный параметр.

refraction_strength

Сила эффекта преломления (от 0.0 до 1.0). Опциональный параметр.

chromatic_aberration

Сила хроматической аберрации для эффекта преломления (от 0.0 до 1.0). Опциональный параметр.

brightness

Коэффициент яркости фона. Значение 1.0 — без изменений. Опциональный параметр.

contrast

Коэффициент контраста фона. Значение 1.0 — без изменений. Опциональный параметр.

saturation

Коэффициент насыщенности фона. Значение 1.0 — без изменений. Опциональный параметр.

rim_highlight_angle

Угол падения света для подсветки краев в градусах. Опциональный параметр.

rim_highlight_fade

Коэффициент затухания подсветки краев (от 0.0 до 1.0). Опциональный параметр.

corner_radius

Радиус скругления всех углов в пикселях. Опциональный параметр.

corner_radii

Массив из 4 значений для индивидуального скругления углов [topLeft, topRight, bottomRight, bottomLeft]. Опциональный параметр.

backdrop_scope

Область поиска фона для эффекта. Опциональный параметр, по умолчанию "card". Доступные значения:

  • "card" — поиск фона ограничивается ближайшим предком Div2View (текущей карточкой). Стандартное поведение.
  • "window" — поиск фона расширяется на все окно приложения. Позволяет захватывать фон за пределами текущей карточки, включая соседние Div2View и нативные виды хоста. Требует Android 13 (API 33) и выше. На более старых версиях Android значение автоматически деградирует до "card".

Важно

Производительность при использовании backdrop_scope: "window"

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

backdrop_id

Идентификатор конкретного view для захвата фона. Если указан вместе с backdrop_scope: "window", поиск тега происходит во всем окне. Если не указан, захватывается всё содержимое окна, находящееся визуально под элементом. Опциональный параметр.

Особенности работы:

  • На Android 13+ (Tiramisu) используется RenderNode для оптимальной производительности
  • На более старых версиях Android используется Canvas для захвата фона
  • Расширение автоматически отслеживает изменения положения и состояния фонового view (скролл, layout, draw)
  • Поддерживает два варианта подсветки краев: простой (Plain) и с отражением (Reflection) для Android 13+
  • Эффект корректно применяется даже к элементам без явно заданного параметра background
  • Нераспознанное значение backdrop_scope приводит к ошибке парсинга и отключению эффекта

Интеграция на Android:

val backdropEffectHandler = BackdropEffectExtensionHandler()
val divConfiguration = DivConfiguration.Builder(imageLoader)
    .extension(backdropEffectHandler)
    .build()
val divContext = DivContext(baseContext = this, configuration = divConfiguration)

Для программной настройки эффектов используйте BackdropEffectDrawable:

val backdropDrawable = BackdropEffectDrawable()
backdropDrawable.setBlurEffect(radius = 10f)
backdropDrawable.setRefractionEffect(height = 5f, strength = 0.5f, chromaticAberration = 0.3f)
backdropDrawable.setColorAdjustment(brightness = 1.2f, contrast = 1.1f, saturation = 0.9f)
backdropDrawable.setRimHighlightEffect(angle = 45f, fade = 0.5f)
backdropDrawable.setCornerRadius(radius = 16f)
// Или для индивидуальных радиусов:
backdropDrawable.setCornerRadii(floatArrayOf(16f, 8f, 8f, 16f))

Пример использования с захватом фона за пределами карточки:

Пример с backdrop_scope: window
{
  "extensions": [
    {
      "id": "backdrop-effect",
      "params": {
        "blur_radius": 15.0,
        "backdrop_scope": "window"
      }
    }
  ]
}

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

Узнать больше

Вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: https://t.me/divkit_community_ru.

Репозиторий DivKit

Предыдущая