---
title: "Android - Отображение пейволов на новом Paywall Builder"
description: "Узнайте, как отображать пейволы на Android для эффективной монетизации."
---

Если вы настроили пейвол с помощью Paywall Builder, вам не нужно беспокоиться о его отрисовке в коде мобильного приложения — пейвол уже содержит всё необходимое: и что показывать, и как показывать.

:::warning

Этот гайд предназначен **только для пейволов на новом Paywall Builder**, которые требуют SDK v3.0. Процесс отображения пейволов различается в зависимости от версии Paywall Builder, а также для Remote Config пейволов и [Observer mode](observer-vs-full-mode).

- Для отображения **Remote Config пейволов** см. [Отрисовка пейвола, созданного через Remote Config](present-remote-config-paywalls).
- Для отображения **пейволов в Observer mode** см. [Android - Отображение пейволов Paywall Builder в Observer mode](android-present-paywall-builder-paywalls-in-observer-mode)

:::

Чтобы получить объект `viewConfiguration`, используемый ниже, см. [Получение пейволов Paywall Builder и их конфигурации](android-get-pb-paywalls).

<Tabs groupId="current-os" queryString>
<TabItem value="views" label="Views" default>

Чтобы отобразить визуальный пейвол на экране устройства, его нужно сначала сконфигурировать. Для этого вызовите метод `AdaptyUI.getPaywallView()` или создайте `AdaptyPaywallView` напрямую:

<Tabs groupId="current-os" queryString>
  <TabItem value="kotlin" label="Kotlin (вариант 1)" default>

```kotlin showLineNumbers
   val paywallView = AdaptyUI.getPaywallView(
       activity,
       viewConfiguration,
       products,
       eventListener,
       insets,
       personalizedOfferResolver,
       tagResolver,
       timerResolver,
   )
```
</TabItem>
<TabItem value="kotlin2" label="Kotlin (вариант 2)" default>

```kotlin showLineNumbers
   val paywallView =
        AdaptyPaywallView(activity) // or retrieve it from xml
   ...
   with(paywallView) {
       showPaywall(
           viewConfiguration,
           products,
					 eventListener,
           insets,
           personalizedOfferResolver,
           tagResolver,
           timerResolver,
       )
   }
```

</TabItem>
<TabItem value="java" label="Java (вариант 1)" default>

```java showLineNumbers
AdaptyPaywallView paywallView = AdaptyUI.getPaywallView(
        activity,
        viewConfiguration,
        products,
        eventListener,
        insets,
        personalizedOfferResolver,
        tagResolver,
        timerResolver
);
```
</TabItem>
<TabItem value="java2" label="Java (вариант 2)" default>

```java showLineNumbers
AdaptyPaywallView paywallView =
  new AdaptyPaywallView(activity); //add to the view hierarchy if needed, or you receive it from xml
...
paywallView.showPaywall(viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver);
```

</TabItem>
<TabItem value="XML" label="XML" default>

```xml showLineNumbers
<com.adapty.ui.AdaptyPaywallView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
```
</TabItem>
</Tabs>

После успешного создания view вы можете добавить его в иерархию представлений и отобразить на экране устройства.

Если вы получаете `AdaptyPaywallView` _не_ через `AdaptyUI.getPaywallView()`, вам также потребуется вызвать метод `.showPaywall()`.

</TabItem>
<TabItem value="compose" label="Jetpack Compose" default>

Чтобы отобразить визуальный пейвол на экране устройства, его нужно сначала сконфигурировать. Для этого используйте следующую composable-функцию:

```kotlin showLineNumbers
AdaptyPaywallScreen(
    viewConfiguration,
    products,
    eventListener,
    insets,
    personalizedOfferResolver,
    tagResolver,
    timerResolver,
)
```
</TabItem>
</Tabs>

Параметры запроса:

| Параметр                      | Обязательность | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| :---------------------------- | :------------- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **viewConfiguration**         | обязательный   | Передайте объект `AdaptyUI.LocalizedViewConfiguration`, содержащий визуальные параметры пейвола. Используйте метод `Adapty.getViewConfiguration(paywall)` для его загрузки. Подробнее см. в разделе [Получение визуальной конфигурации пейвола](android-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder).                                                                                                                       |
| **products**                  | необязательный | Передайте массив `AdaptyPaywallProduct` для оптимизации времени отображения продуктов на экране. Если передать `null`, AdaptyUI автоматически загрузит необходимые продукты.                                                                                                                                                                                                                                                                                           |
| **eventListener**             | необязательный | Передайте `AdaptyUiEventListener` для отслеживания событий пейвола. Рекомендуется расширять `AdaptyUiDefaultEventListener` для удобства использования. Подробнее см. в разделе [Обработка событий пейвола](android-handling-events).                                                                                                                                                                                                                                  |
| **insets**                    | необязательный | <p>Отступы вокруг пейвола, которые не позволяют интерактивным элементам скрываться за системными панелями.</p><p>По умолчанию: `UNSPECIFIED` — Adapty автоматически подбирает отступы, что отлично работает для пейволов от края до края.</p><p>Если ваш пейвол не является edge-to-edge, вы можете задать пользовательские отступы. Подробнее читайте в разделе [Изменение отступов пейвола](android-present-paywalls#change-paywall-insets) ниже.</p>              |
| **personalizedOfferResolver** | необязательный | Чтобы указать персонализированную цену ([подробнее](https://developer.android.com/google/play/billing/integrate#personalized-price)), реализуйте `AdaptyUiPersonalizedOfferResolver` и передайте собственную логику, которая возвращает `true` для `AdaptyPaywallProduct`, если цена продукта персонализирована, и `false` в противном случае.                                                                                                                         |
| **tagResolver**               | необязательный | Используйте `AdaptyUiTagResolver` для обработки кастомных тегов в тексте пейвола. Этот resolver принимает тег в качестве параметра и возвращает соответствующую строку. Подробнее см. в разделе [Кастомные теги в Paywall Builder](custom-tags-in-paywall-builder).                                                                                                                                                                                                    |
| **timerResolver**             | необязательный | Передайте resolver, если планируете использовать функциональность кастомных таймеров.                                                                                                                                                                                                                                                                                                                                                                                 |

:::tip

Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции.

:::

## Изменение отступов пейвола \{#change-paywall-insets\}

Отступы — это пространство вокруг пейвола, которое не позволяет интерактивным элементам скрываться за системными панелями. По умолчанию Adapty автоматически подбирает отступы, что отлично работает для пейволов от края до края.

Если ваш пейвол не является edge-to-edge, вы можете задать пользовательские отступы:

- Если ни строка состояния, ни панель навигации не перекрывают `AdaptyPaywallView`, используйте `AdaptyPaywallInsets.NONE`.
- Для более сложных случаев, например когда пейвол перекрывается верхней строкой состояния, но не нижней панелью, можно задать только `bottomInset` равным `0`, как показано в примере ниже:

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers

//create extension function
fun View.onReceiveSystemBarsInsets(action: (insets: Insets) -> Unit) {
    ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
        val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
        ViewCompat.setOnApplyWindowInsetsListener(this, null)
        action(systemBarInsets)
        insets
    }
}
//and then use it with the view
paywallView.onReceiveSystemBarsInsets { insets ->
    val paywallInsets = AdaptyPaywallInsets.vertical(insets.top, 0)
    paywallView.showPaywall(
           viewConfiguration,
           products,
					 eventListener,
           paywallInsets,
           personalizedOfferResolver,
           tagResolver,
           timerResolver,
       )
}
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

...

ViewCompat.setOnApplyWindowInsetsListener(paywallView, (view, insets) -> {
    Insets systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars());
    ViewCompat.setOnApplyWindowInsetsListener(paywallView, null);
  
    AdaptyPaywallInsets paywallInsets =
                AdaptyPaywallInsets.of(systemBarInsets.top, 0);
    paywallView.showPaywall(paywall, products, viewConfiguration, paywallInsets, productTitleResolver);
            
    return insets;
});
```
</TabItem>
</Tabs> 

## Использование таймеров, определённых разработчиком \{#use-developer-defined-timer\}

Чтобы использовать кастомные таймеры в мобильном приложении, создайте объект `timerResolver` — словарь или карту, связывающую кастомные таймеры со строковыми значениями, которые будут подставляться при отрисовке пейвола. Вот пример:

<Tabs groupId="current-os" queryString> 
<TabItem value="kotlin" label="Kotlin" default> 

```kotlin showLineNumbers

...

val customTimers = mapOf(
    "CUSTOM_TIMER_NY" to Calendar.getInstance(TimeZone.getDefault()).apply { set(2025, 0, 1) }.time, // New Year 2025
)
val timerResolver = AdaptyUiTimerResolver { timerId ->
    customTimers.getOrElse(timerId, { Date(System.currentTimeMillis() + 3600 * 1000L) /* in 1 hour */ } )
}
```

</TabItem> 
<TabItem value="java" label="Java" default> 

```JAVA showLineNumbers

...

Map<String, Date> customTimers = new HashMap<>();
customTimers.put(
        "CUSTOM_TIMER_NY",
        new Calendar.Builder().setTimeZone(TimeZone.getDefault()).setDate(2025, 0, 1).build().getTime()
);
AdaptyUiTimerResolver timerResolver = new AdaptyUiTimerResolver() {
    @NonNull
    @Override
    public Date timerEndAtDate(@NonNull String timerId) {
        Date date = customTimers.get(timerId);
        return date != null ? date : new Date(System.currentTimeMillis() + 3600 * 1000L); /* in 1 hour */
    }
};
```

</TabItem> 

</Tabs>

В этом примере `CUSTOM_TIMER_NY` — это **Timer ID** кастомного таймера, заданного в дашборде Adapty. `timerResolver` обеспечивает динамическое обновление таймера корректным значением — например, `13д 09ч 03м 34с` (вычисляется как время окончания таймера, например Новый год, минус текущее время).

## Использование кастомных тегов \{#use-custom-tags\}

Чтобы использовать кастомные теги в мобильном приложении, создайте объект `tagResolver` — словарь или карту, связывающую кастомные теги со строковыми значениями, которые будут подставляться при отрисовке пейвола. Вот пример:

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers
val customTags = mapOf("USERNAME" to "John")
val tagResolver = AdaptyUiTagResolver { tag -> customTags[tag] }
```

</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Map<String, String> customTags = new HashMap<>();
customTags.put("USERNAME", "John");
AdaptyUiTagResolver tagResolver = customTags::get;
```

</TabItem>
</Tabs>

В этом примере `USERNAME` — это кастомный тег, введённый в дашборде Adapty как `<USERNAME/>`. `tagResolver` обеспечивает динамическую замену этого кастомного тега на указанное значение — например, `John`.

Рекомендуем создавать и заполнять `tagResolver` непосредственно перед отображением пейвола. Как только он будет готов, передайте его в метод AdaptyUI, который вы используете для отображения пейвола.

## Изменение цвета индикатора загрузки пейвола \{#change-paywall-loading-indicator-color\}

Вы можете переопределить цвет индикатора загрузки по умолчанию следующим образом:

```XML showLineNumbers title = "XML"

<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar">
    
    <item name="adapty_progressIndicatorColor">@color/yourColor</item>
</style>
```