---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ads.yandex.com/helpcenter/en/dev/android7/adaptive-sticky-banner.md
  - https://ads.yandex.com/helpcenter/ru/dev/android7/adaptive-sticky-banner.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/en/llms.txt

# Adaptive sticky banner

<!-- source: en/dev/_includes7/adaptive-sticky-banner.md -->
That is a small, automatically updated ad placed at the top or bottom of the app screen. It does not overlap the main app content and is often used in game apps.
<!-- endsource: en/dev/_includes7/adaptive-sticky-banner.md -->

<!-- source: en/dev/_includes7/adaptive-sticky-banner.md -->
Adaptive sticky banners provide maximum efficiency by optimizing the size of the ad on each device. This ad type lets developers set a maximum allowable ad width, though the optimal ad size is still determined automatically. The height of the adaptive sticky banner shouldn't exceed 15% of the screen height.
<!-- endsource: en/dev/_includes7/adaptive-sticky-banner.md -->

{% cut "Appearance" %}

<img src="https://yastatic.net/s3/doc-binary/src/docs/support/mobile-ads/en/monetization/_images/banner-sticky-en-ex.png" width="200">

{% endcut %}

This guide covers the process of integrating adaptive sticky banners into Android apps.
Besides code samples and instructions, it contains format-specific recommendations and links to additional resources.


## Prerequisite {#pre}

<!-- source: en/dev/_includes7/pre-android.md -->
1. Follow the SDK integration steps described in [Quick start](https://ads.yandex.com/helpcenter/en/dev/android7/quick-start.md).
2. [Initialize](https://ads.yandex.com/helpcenter/en/dev/android7/quick-start.md#init) your ad SDK in advance.
3. Make sure you're running the latest [Yandex Mobile Ads SDK](https://ads.yandex.com/helpcenter/en/dev/android7/changelog-android.md) version. If you're using mediation, make sure you're also running the latest version of the [unified build](https://ads.yandex.com/helpcenter/en/dev/android7/changelog-android.md).
<!-- endsource: en/dev/_includes7/pre-android.md -->

## Implementation {#implement}

Key steps for integrating adaptive sticky banners:

* Create and configure a view for displaying banner ads.
* Register a callback listener.
* Load the ad.
* Pass [additional settings](https://ads.yandex.com/helpcenter/en/dev/android7/target-adfox.md) if you're using Adfox.

## Features of adaptive sticky banner integration {#features}

1. All calls to Yandex Mobile Ads SDK methods must be made from the main thread.

2. If the `onAdFailedToLoad()` callback returns an error, don't try to load a new ad again. If there's no other option, limit the number of ad load retries. This will help avoid constant unsuccessful requests and connection issues if there are limitations.

3. Adaptive sticky banners work best when utilizing the full available width. In most cases, this will be the full width of the device screen. Be sure to consider the padding parameters set in your app and the display's safe area.

4. To get the size of the ad, use the method `BannerAdSize.stickySize(context, adWidth)`, which accepts the context and available width of the ad container as arguments.

5. If you have meditation enabled, we strongly recommend waiting for initialization to complete before calculating the size of the sticky banner. Until the initialization is complete, only a preliminary size is available, which may change after obtaining the accurate settings.

6. The ad width and height values contained within a `BannerAdSize` object that was calculated using the `BannerAdSize.stickySize(context, adWidth)` method are consistent across the same device. When testing your app's layout on a specific device, you can be sure that the ad size for that device will remain the same.

7. The height of an adaptive sticky banner never exceeds 15% of the screen height and can't be less than 50 dp.

## Adding an ad view to the app layout {#add-view}

To display banner ads, add BannerAdView to your app layout. You can do that programmatically or by using an XML file.

Example of adding BannerAdView to an app screen layout:

```xml
# activity.xml
...
<com.yandex.mobile.ads.banner.BannerAdView
        android:id="@+id/ad_container_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent" />
...
```

You can also create a `BannerAdView` instance programmatically:

{% list tabs %}

   - Kotlin

     ```kotlin
     val bannerAd = BannerAdView(this)
     ```

   - Java

     ```java
     final BannerAdView bannerAd = new BannerAdView(this);
     ```
{% endlist %}

## Loading and rendering ads {#load}

Once you created and added BannerAdView to the app screen, you need to load the ads. Before loading an adaptive sticky banner, calculate the ad size for each device.

This is done automatically via the SDK API method: `BannerAdSize.stickySize(context, adWidth)`.

Pass the context and the maximum acceptable ad container width as arguments. We recommend using the full width of the device screen or the width of the parent container. Be sure to consider the padding parameters set in your app and the display's safe area:

{% list tabs %}

   - Kotlin

     ```kotlin
     private val adSize: BannerAdSize
         get() {
             // Calculate the width of the ad, taking into account the padding in the ad container.
             var adWidthPixels = binding.adContainerView.width
             if (adWidthPixels == 0) {
                 // If the ad hasn't been laid out, default to the full screen width
                 adWidthPixels = resources.displayMetrics.widthPixels
             }
             val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()

             return BannerAdSize.stickySize(this, adWidth)
         }
     ```

   - Java

     ```java
     @NonNull
     private BannerAdSize getAdSize() {
         final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
         // Calculate the width of the ad, taking into account the padding in the ad container.
         int adWidthPixels = mBinding.adContainerView.getWidth();
         if (adWidthPixels == 0) {
             // If the ad hasn't been laid out, default to the full screen width
             adWidthPixels = displayMetrics.widthPixels;
         }
         final int adWidth = Math.round(adWidthPixels / displayMetrics.density);

         return BannerAdSize.stickySize(this, adWidth);
     }
     ```
{% endlist %}

To load ads, you also need the Activity context and the ad unit ID you obtained in the Yandex Advertising Network interface (adUnitId).

To enable notifications when ads load or fail to load and track an adaptive sticky banner's lifecycle events, set the `BannerAdEventListener` callback listener for the BannerAdView class instance.

You can extend ad request parameters with the `AdRequest.Builder()` class to include information about the user's interests, page context, location, and other additional data in the ad request. Extra context added to ad requests can greatly improve the ad quality. To learn more, see [Ad targeting](https://ads.yandex.com/helpcenter/en/dev/android7/target.md).

The example below shows how to load an adaptive sticky banner. Once loaded, the banner is displayed automatically:

{% list tabs %}

   - Kotlin

     ```kotlin
     class StickyBannerAdActivity : AppCompatActivity(R.layout.activity_sticky_banner_ad) {
         private var bannerAd: BannerAdView? = null
         private lateinit var binding: ActivityStickyBannerAdBinding

         private val adSize: BannerAdSize
             get() {
                 // Calculate the width of the ad, taking into account the padding in the ad container.
                 var adWidthPixels = binding.adContainerView.width
                 if (adWidthPixels == 0) {
                     // If the ad hasn't been laid out, default to the full screen width
                     adWidthPixels = resources.displayMetrics.widthPixels
                 }
                 val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()

                 return BannerAdSize.stickySize(this, adWidth)
             }

         override fun onCreate(savedInstanceState: Bundle?) {
             super.onCreate(savedInstanceState)
             binding = ActivityStickyBannerAdBinding.inflate(layoutInflater)
             setContentView(binding.root)

             // Since we're loading the banner based on the adContainerView size,
             // we need to wait until this view is laid out before we can get the width
             binding.adContainerView.viewTreeObserver.addOnGlobalLayoutListener(object :
                 ViewTreeObserver.OnGlobalLayoutListener {
                 override fun onGlobalLayout() {
                     binding.adContainerView.viewTreeObserver.removeOnGlobalLayoutListener(this);
                     bannerAd = loadBannerAd(adSize)
                 }
             })
         }

         private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
             return binding.banner.apply {
                 setAdSize(adSize)
                 setAdUnitId("your-ad-unit-id")
                 setBannerAdEventListener(object : BannerAdEventListener {
                     override fun onAdLoaded() {
                         // If this callback occurs after the activity is destroyed, you
                         // must call destroy and return or you may get a memory leak.
                         // Note `isDestroyed` is a method on Activity.
                         if (isDestroyed) {
                             bannerAd?.destroy()
                             return
                         }
                     }

                     override fun onAdFailedToLoad(adRequestError: AdRequestError) {
                         // Ad failed to load with AdRequestError.
                         // Attempting to load a new ad from the onAdFailedToLoad() method is strongly discouraged.
                     }

                     override fun onAdClicked() {
                         // Called when a click is recorded for an ad.
                     }

                     override fun onLeftApplication() {
                         // Called when the user is about to leave the application (e.g., to go to the browser), as a result of clicking on the ad.
                     }

                     override fun onReturnedToApplication() {
                         // Called when the user returns to the application after a click.
                     }

                     override fun onImpression(impressionData: ImpressionData?) {
                         // Called when an impression is recorded for an ad.
                     }
                 })
                 loadAd(
                     AdRequest.Builder()
                         // Methods in the AdRequest.Builder class can be used here to specify individual options settings.
                         .build()
                 )
             }
         }
     }
     ```

   - Java

     ```java
     public class StickyBannerAdActivity extends AppCompatActivity {
         @Nullable
         private BannerAdView mBannerAd = null;
         private ActivityStickyBannerAdBinding mBinding;

         public StickyBannerAdActivity() {
             super(R.layout.activity_sticky_banner_ad);
         }

         @Override
         protected void onCreate(@Nullable Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             mBinding = ActivityStickyBannerAdBinding.inflate(getLayoutInflater());
             setContentView(mBinding.getRoot());

             // Since we're loading the banner based on the adContainerView size,
             // we need to wait until this view is laid out before we can get the width
             mBinding.adContainerView.getViewTreeObserver().addOnGlobalLayoutListener(
                     new ViewTreeObserver.OnGlobalLayoutListener() {
                         @Override
                         public void onGlobalLayout() {
                             mBinding.adContainerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             mBannerAd = loadBannerAd(getAdSize());
                         }
                     }
             );
         }

         @NonNull
         private BannerAdSize getAdSize() {
             final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
             // Calculate the width of the ad, taking into account the padding in the ad container.
             int adWidthPixels = mBinding.adContainerView.getWidth();
             if (adWidthPixels == 0) {
                 // If the ad hasn't been laid out, default to the full screen width
                 adWidthPixels = displayMetrics.widthPixels;
             }
            final int adWidth = Math.round(adWidthPixels / displayMetrics.density);

             return BannerAdSize.stickySize(this, adWidth);
         }

         @NonNull
         private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
             final BannerAdView bannerAd = mBinding.banner;
             bannerAd.setAdSize(adSize);
             bannerAd.setAdUnitId("your-ad-unit-id");
             bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
                 @Override
                 public void onAdLoaded() {
                     // If this callback occurs after the activity is destroyed, you
                     // must call destroy and return or you may get a memory leak.
                     // Note `isDestroyed` is a method on Activity.
                     if (isDestroyed() && mBannerAd != null) {
                         mBannerAd.destroy();
                     }
                 }

                 @Override
                 public void onAdFailedToLoad(@NonNull final AdRequestError adRequestError) {
                     // Ad failed to load with AdRequestError.
                     // Attempting to load a new ad from the onAdFailedToLoad() method is strongly discouraged.
                 }

                 @Override
                 public void onAdClicked() {
                     // Called when a click is recorded for an ad.
                 }

                 @Override
                 public void onLeftApplication() {
                     // Called when the user is about to leave the application (e.g., to go to the browser), as a result of clicking on the ad.
                 }

                 @Override
                 public void onReturnedToApplication() {
                     // Called when the user returns to the application after a click.
                 }

                 @Override
                 public void onImpression(@Nullable ImpressionData impressionData) {
                     // Called when an impression is recorded for an ad.
                 }
             });
             final AdRequest adRequest = new AdRequest.Builder()
                     // Methods in the AdRequest.Builder class can be used here to specify individual options settings.
                     .build();
             bannerAd.loadAd(adRequest);
             return bannerAd;
         }
     }
     ```
{% endlist %}

<!-- source: en/dev/_includes7/ad-attributes.md -->
If you serve ads through Adfox, then after the banner ad response, the `campaignId`, `bannerId`, and `placeId` data can be accessed from the `BannerAdView` objects using the `adAttributes` property of the `AdAttributes` type.
<!-- endsource: en/dev/_includes7/ad-attributes.md -->

## Releasing resources {#destroy}

If a callback occurs after the Activity is destroyed, call the `destroy()` function for the used ad object to release resources:

{% list tabs %}

   - Kotlin

     ```kotlin
     private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
         return binding.banner.apply {
             setBannerAdEventListener(object : BannerAdEventListener {
                 override fun onAdLoaded() {
                     // If this callback occurs after the activity is destroyed, you
                     // must call destroy and return or you may get a memory leak.
                     // Note `isDestroyed` is a method on Activity.
                     if (isDestroyed) {
                         bannerAd?.destroy()
                         return
                     }
                 }
                 ...
             })
             ...
         }
     }
     ```

   - Java

     ```java
     @NonNull
     private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
         final BannerAdView bannerAd = mBinding.banner;
         bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
             @Override
             public void onAdLoaded() {
                 // If this callback occurs after the activity is destroyed, you
                 // must call destroy and return or you may get a memory leak.
                 // Note `isDestroyed` is a method on Activity.
                 if (isDestroyed() && mBannerAd != null) {
                     mBannerAd.destroy();
                 }
             }
             ...
         });
         ...
         return bannerAd;
     }
     ```
{% endlist %}

## Testing adaptive sticky banner integration {#test}

<!-- source: en/dev/_includes7/test-android-sticky-banner.md -->
### Using demo ad units for ad testing {#demo-blocks}

We recommend using test ads to test your adaptive sticky banner integration and your app itself.

To guarantee that test ads are returned for every ad request, we created a special demo ad placement ID. Use it to check your ad integration.

Demo adUnitId: `demo-banner-yandex`.

{% note warning %}

Before publishing your app in the store, make sure to replace the demo ad placement ID with a real one obtained from the Yandex Advertising Network interface.

{% endnote %}

You can find the list of available demo ad placement IDs in the [Demo ad units for testing](https://ads.yandex.com/helpcenter/en/dev/android7/demo-blocks.md) section.

### Testing ad integration {#test-int}

You can check your adaptive sticky banner integration using the SDK's built-in analyzer.

The tool makes sure your ads are integrated properly and outputs a detailed report to the log.
To view the report, search for the “YandexAds” keyword in the [Logcat](https://developer.android.com/studio/command-line/logcat) tool for Android app debugging.

```bash
adb logcat -v brief '*:S YandexAds'
```

If the integration is successful, you'll see this message:
```bash
adb logcat -v brief '*:S YandexAds'
mobileads$ adb logcat -v brief '*:S YandexAds'
I/YandexAds(13719): [Integration] Ad type banner was integrated successfully
```

If you're having problems integrating banner ads, you'll get a detailed report on the issues and recommendations for how to fix them.
<!-- endsource: en/dev/_includes7/test-android-sticky-banner.md -->

## Additional resources {#resources}

* <!-- source: en/dev/_includes7/github-pubdev-links.md -->
  Link to [GitHub](https://github.com/yandexmobile/yandex-ads-sdk-android).
  <!-- endsource: en/dev/_includes7/github-pubdev-links.md -->
