Кампании и рекомендации в Android
Сначала подключите SDK и опубликуйте кампанию в приложении. Навигация по URL/deeplink реализуется в приложении через callback.
In-App кампании
SDK автоматически отображает in-app-кампании, если они приходят в ответ на trackView(...) или triggerEvent(...).
Автопоказ поддерживает MODAL, BOTTOM_SHEET, FULL_SCREEN и SNACK_BAR. Ответ должен содержать непустой variables.elements; INLINE в этот flow не выводится. SDK проверяет, что Activity не уничтожена и не завершается, и учитывает presentation lock.
Приложение отвечает за:
- корректный
PageContext; - корректный
activityContext; - обработку действий пользователя через
gravityEventCallback. Блокировка новых in-app показов описана в Конфигурации.
GravityInlineView
Используйте GravityInlineView, если экран построен на XML.
<ai.gravityfield.gravity_sdk.ui.GravityInlineView
android:id="@+id/recommendationsView"
android:layout_width="match_parent"
android:layout_height="250dp"
app:selector=""homepage-recs""
app:color="#FFF1F1F1"
app:cornerRadius="20dp" />
После инфлейта обязательно передайте PageContext:
val inlineView = findViewById<GravityInlineView>(R.id.recommendationsView)
inlineView.init(
PageContext(
type = ContextType.HOMEPAGE,
data = emptyList(),
location = "app://homepage",
)
)
Поддерживаемые XML-атрибуты:
GravityInlineCompose
Используйте GravityInlineCompose, если экран написан на Jetpack Compose.
GravityInlineCompose(
modifier = Modifier
.fillMaxWidth()
.height(250.dp),
selector = JSONObject.quote("homepage-recs"),
pageContext = PageContext(
type = ContextType.HOMEPAGE,
data = emptyList(),
location = "app://homepage",
),
loader = { CircularProgressIndicator() },
)
loader - это composable для состояния загрузки. Если placeholder не нужен, можно передать loader = null.
GravityInlineListView
GravityInlineListView используется для отображения нескольких inline-элементов из одной группы.
<ai.gravityfield.gravity_sdk.ui.GravityInlineListView
android:id="@+id/inlineListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:groupSelector=""homepage-group"" />
val inlineListView = findViewById<GravityInlineListView>(R.id.inlineListView)
inlineListView.init(
PageContext(
type = ContextType.HOMEPAGE,
data = emptyList(),
location = "app://homepage",
)
)
Этот компонент полезен для сценариев, где несколько блоков должны быть загружены одной группой кампаний.
Кэш inline-блоков
GravityInlineView, GravityInlineCompose и GravityInlineListView используют кэш, чтобы восстановить контент и позицию скролла при пересоздании view. Это важно для экранов с RecyclerView, повторным использованием view и несколькими inline-блоками на одном экране.
Кэш привязан к полному ключу:
- для
GravityInlineViewиGravityInlineCompose-selector + PageContext; - для
GravityInlineListView-groupSelector + PageContext.
SDK не очищает inline-кэш автоматически, потому что не знает, закрыт экран окончательно или view будет переиспользована. При закрытии экрана сбросьте кэш самостоятельно:
class InlineDemoActivity : AppCompatActivity() {
private val pageContext = PageContext(
type = ContextType.HOMEPAGE,
data = emptyList(),
location = "app://homepage",
)
override fun onDestroy() {
if (isFinishing) {
GravitySDK.instance.resetInlineViewCache(
selector = JSONObject.quote("homepage-recs"),
pageContext = pageContext,
)
}
super.onDestroy()
}
}
Для GravityInlineListView используйте отдельный метод:
GravitySDK.instance.resetInlineListViewCache(
groupSelector = JSONObject.quote("homepage-group"),
pageContext = pageContext,
)
Если на экране несколько inline-блоков, сбрасывайте кэш для каждого selector или groupSelector, который использовался на этом экране. Для Fragment/Compose выбирайте момент окончательного выхода из маршрута; уничтожение view при смене конфигурации не всегда означает закрытие экрана. Сброс удаляет данные кэша, но не запускает повторную загрузку уже отображённого view.
Используйте тот же экземпляр значения selector/groupSelector, включая JSON-кодирование, и тот же PageContext, что при загрузке. Отличие любого поля контекста создаёт другой ключ.
Карточки товаров
ProductViewBuilder нужен для отображения карточек товара в блоке рекомендаций. Для карточек в дизайне приложения передайте SDK свой шаблон. Если builder отсутствует, Android использует демонстрационную GravityProduct; не рассчитывайте на неё как на карточку вашего приложения.
SDK получает recommendation-блок, управляет контейнером, списком слотов и tracking-контекстом, но сам шаблон товарной карточки задает приложение. Разработчик реализует ProductViewBuilder или LegacyProductViewBuilder и передает его в GravitySDK.initialize(...) через параметр productViewBuilder.
После этого SDK использует переданный шаблон для каждого товара в product/recommendation-блоках: вызывает builder для каждого slot и передает в него slot, content и campaign. Поэтому карточка отображается как native UI приложения, а не как готовая карточка, нарисованная SDK.
slot содержит данные одного рекомендованного товара:
slot.item- словарь с полями товара из фида или из запрошенныхfields: напримерsku,name,price,old_price,image_url,url,brand,currencyи другие кастомные поля;slot.strIdиslot.slotId- идентификаторы позиции товара в выдаче;slot.fallback- признак, что товар пришел из fallback-логики;slot.events- tracking-данные товара, которые SDK использует при отправке engagement.
Названия ключей в slot.item должны совпадать с вашим фидом и настройкой fields. Например, если в ответе приходит imageUrl, читайте imageUrl; если используется поле фида image_url, читайте image_url.
Важно:
- SDK автоматически отслеживает visible impression товара во встроенном блоке;
- клик по товару в кастомной карточке нужно отправлять вручную через
sendProductEngagement(...).
Пример шаблона карточки для Jetpack Compose:
Полный пример: product_view_builder.kt. Он использует Coil 3.1.0; зависимости для загрузки изображений. Замените package на package приложения, реализуйте openProduct и передайте MyComposeProductViewBuilder в initialize.
Кто отправляет engagement
Успешная загрузка автоматически отправляет content load tracking. Встроенные UI-компоненты отправляют показы контента, видимость товаров и tracking для поддерживаемых действий. Карточка из ProductViewBuilder уже обёрнута detector SDK: вручную отправляйте её клик перед навигацией, не дублируйте visible impression.
Ручные вызовы engagement не генерируют tracking callback. Для собственного UI используйте отдельные правила аналитики.
Android ждёт видимость не менее 50% в течение секунды; после выхода и возвращения событие может повториться.