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

# 自适应内联横幅

<!-- source: zh/dev/_includes/adaptive-inline-banner.md -->
自适应内嵌横幅广告是一种灵活的横幅广告格式，通过针对每台设备优化广告尺寸，确保投放效果达到最优。
<!-- endsource: zh/dev/_includes/adaptive-inline-banner.md -->

<!-- source: zh/dev/_includes/adaptive-inline-banner.md -->
借助这种广告类型，开发者可设置广告允许的最大宽度和高度，系统将自动确定最佳广告尺寸。为了选择最佳广告尺寸，自适应内嵌横幅广告采用最大高度而非固定高度，这有助于提升广告表现。
<!-- endsource: zh/dev/_includes/adaptive-inline-banner.md -->

通常，这种格式在基于内容来源的应用或允许主要关注广告的上下文环境中使用。

{% cut "外观" %}

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

{% endcut %}

本指南展示了如何将自适应内联横幅集成到 Android 应用中。
除了代码示例和说明之外，它还包含特定格式的建议和其他资源的链接。

## 前提条件 {#pre}

<!-- source: zh/dev/_includes/pre-android.md -->
1. 按照[快速入门](https://ads.yandex.com/helpcenter/zh/dev/android/quick-start.md) 中描述的 SDK 集成步骤进行操作。
2. 首先，您需要[初始化](https://ads.yandex.com/helpcenter/zh/dev/android/quick-start.md#init) 广告 SDK。
3. 确保您使用的是[最新Yandex Mobile Ads SDK 版本](https://ads.yandex.com/helpcenter/zh/dev/android/changelog-android.md)。如果您使用的是广告中介服务，请更新至最新的[单一构建版本](https://ads.yandex.com/helpcenter/zh/dev/android/changelog-android.md)。
<!-- endsource: zh/dev/_includes/pre-android.md -->

## 实施 {#implement}

集成自适应内联横幅的关键步骤：

* 创建并配置用于显示横幅广告的视图。
* 注册回调方法监听器。
* 加载广告。
* 如果您使用 Adfox，请传递 [其他设置](https://ads.yandex.com/helpcenter/zh/dev/android/target-adfox.md)。

## 自适应内联横幅集成的特点 {#features}

1. 所有调用 Yandex Mobile Ads SDK 方法的操作必须在主线程中完成。

2. 要在应用的屏幕上成功展示视频广告，您需要启用 [硬件加速](https://developer.android.com/guide/topics/graphics/hardware-accel)。默认情况下启用硬件加速，但某些应用会将其禁用。如果这种情况适用于您的应用，我们建议为使用广告的活动类别启用硬件加速。

3. 如果您在 `onAdFailedToLoad()` 回调中收到错误，请不要尝试再次加载新广告。如果没有其他选项，请限制广告加载重试次数。这将有助于避免出现限制时持续出现不成功的请求和连接问题。

4. 为了确保自适应内联横幅正常运行，您需要 [使应用布局自适应](https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes)。否则，您的广告可能无法正确呈现。

5. 自适应内联横幅在使用所有可用宽度时效果最佳。通常情况下，这是设备屏幕的全宽度。确保包括适用于您的应用程序的所有内边距和安全显示区域。

6. 自适应内联横幅设计用于放置在可滚动内容中。广告的高度可以与设备屏幕相同，也可以限制为最大高度，具体取决于 API。

7. 要获取广告尺寸，请使用 `BannerAdSize.inlineSize(context, adWidth, maxAdHeight)` 方法，该方法接受广告上下文、广告容器的可用宽度以及可接受的最大广告高度作为参数。

8. `BannerAdSize` 对象是使用 `BannerAdSize.inlineSize(context, adWidth, maxAdHeight)` 方法计算的，其中包含用于在后端选择最有效的广告尺寸的技术数据。广告的高度可能会在每次加载时发生变化。收到广告加载成功消息后即可获取广告的实际宽度和高度。

## 插屏内联横幅的呈现规则 {#banner-assets}

<!-- source: zh/dev/_includes/banner-assets.md -->
1. 顶部不可点击安全区域的高度为 80 dp。该区域内的控件可以点击。

1. 视觉元素（素材）的尺寸必须至少为 32×32 dp，包括关闭按钮及其他所有图标。

1. 素材周围的可点击区域必须至少为 64×64 dp。例如，如果素材的尺寸为 32×32 dp，则其四周需有足够的内边距，以确保总可点击区域达到 64×64 dp。

1. 如果控件有延迟出现，必须显示一个计时器或进度条，直到元素加载完成。

{% cut "示例" %}

![](../../_images/common/banner-assets.png)

{% endcut %}
<!-- endsource: zh/dev/_includes/banner-assets.md -->

## 将广告视图添加到应用布局 {#add-view}

要显示横幅广告，您需要将 `BannerAdView` 添加到应用布局中。您可以通过编程方式或使用 XML 文件来完成此操作。

将 `BannerAdView` 添加到应用屏幕布局的示例：
```xml
# activity.xml
...
<com.yandex.mobile.ads.banner.BannerAdView
        android:id="@+id/banner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
...
```

您还可以通过编程方式创建 `BannerAdView` 对象：

{% list tabs %}

- Kotlin

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

- Java

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

## 加载和呈现广告 {#load}

创建`BannerAdView` 并将其添加到应用屏幕后，需要加载广告。在加载自适应内联横幅之前，还必须针对每个设备计算广告尺寸。

该操作通过 SDK API 自动执行：`BannerAdSize.inlineSize(context, adWidth, maxAdHeight)`。
作为参数，传递广告容器的最大允许宽度。建议使用设备屏幕的整个宽度或父容器的宽度。确保包括适用于您的应用的所有内边距和安全显示区域。

{% list tabs %}

- Kotlin

   ```kotlin
   private val adSize: BannerAdSize
       get() {
           val screenHeight = resources.displayMetrics.run { heightPixels / density }.roundToInt()
           // 计算广告的宽度，同时考虑广告容器中的内边距。
           var adWidthPixels = binding.adContainerView.width
           if (adWidthPixels == 0) {
               // 如果广告尚未布局，则默认为全屏宽度
               adWidthPixels = resources.displayMetrics.widthPixels
           }
           val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()
           val maxAdHeight = screenHeight / 2

           return BannerAdSize.inlineSize(context, adWidth, maxAdHeight)
       }
   ```

- Java

   ```java
   @NonNull
   private BannerAdSize getAdSize() {
       final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
       final int screenHeight = Math.round(displayMetrics.heightPixels / displayMetrics.density);
       // 计算广告的宽度，同时考虑广告容器中的内边距。
       int adWidthPixels = mBinding.adContainerView.getWidth();
       if (adWidthPixels == 0) {
           // 如果广告尚未布局，则默认为全屏宽度
           adWidthPixels = displayMetrics.widthPixels;
       }
       final int adWidth = Math.round(adWidthPixels / displayMetrics.density);
       // 确定允许的最大广告高度。以当前值为例。
       final int maxAdHeight = screenHeight / 2;

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

要加载广告，您还需要来自 Yandex Advertising Network 界面的广告单元 ID (adUnitId)。

要在广告加载或加载失败时发出通知并跟踪自适应内联横幅的生命周期，请为 `BannerAdView` 类对象设置 `BannerAdEventListener` 回调方法监听器。

您可以通过 `AdRequest.Builder()` 在请求中传递用户兴趣、上下文应用数据、位置详细信息或其他数据来扩展广告请求参数。在请求中提供额外的上下文数据可以显著提高您的广告质量。请参阅[广告定位](https://ads.yandex.com/helpcenter/zh/dev/android/target.md)版块了解更多信息。

以下示例展示了如何加载自适应内联横幅。加载成功后，会自动显示横幅：

{% list tabs %}

- Kotlin

   ```kotlin
   class AdaptiveInlineBannerAdActivity : AppCompatActivity(R.layout.activity_inline_banner_ad) {
       private var bannerAd: BannerAdView? = null
       private lateinit var binding: ActivityInlineBannerAdBinding

       private val adSize: BannerAdSize
           get() {
               val screenHeight = resources.displayMetrics.run { heightPixels / density }.roundToInt()
               // 计算广告的宽度，同时考虑广告容器中的内边距。
               var adWidthPixels = binding.adContainerView.width
               if (adWidthPixels == 0) {
                   // 如果广告尚未布局，则默认为全屏宽度
                   adWidthPixels = resources.displayMetrics.widthPixels
               }
               val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()
               // 确定允许的最大广告高度。以当前值为例。
               val maxAdHeight = screenHeight / 2

               return BannerAdSize.inlineSize(context, adWidth, maxAdHeight)
           }

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

           // 由于我们根据 adContainerView 大小加载横幅，
           // 我们需要等到该视图布局完毕后才能获取宽度
           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() {
                       // 如果此回调发生在活动被销毁之后，您
                       // 必须调用 destroy 和 return，否则可能会出现内存泄漏。
                       // 注意 `isDestroyed` 是活动上的一个方法。
                       if (isDestroyed) {
                           bannerAd?.destroy()
                           return
                       }
                   }

                   override fun onAdFailedToLoad(adRequestError: AdRequestError) {
                       // 广告加载失败，出现 AdRequestError。
                       // 强烈建议不要尝试通过 onAdFailedToLoad() 方法加载新广告。
                   }

                   override fun onAdClicked() {
                       // 记录广告点击时调用。
                   }

                   override fun onLeftApplication() {
                       // 当用户由于点击广告而即将离开应用程序（例如，转到浏览器）时调用。
                   }

                   override fun onReturnedToApplication() {
                       // 当用户点击后返回应用程序时调用。
                   }

                   override fun onImpression(impressionData: ImpressionData?) {
                       // 记录广告展示次数时调用。
                   }
               })
               loadAd(
                   AdRequest.Builder()
                       // 此处可以使用 AdRequest.Builder 类中的方法来指定各个选项设置。
                       .build()
               )
           }
       }
   }
   ```

- Java

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

       public AdaptiveInlineBannerAdActivity() {
           super(R.layout.activity_inline_banner_ad);
       }

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

           // 由于我们根据 adContainerView 大小加载横幅，
           // 我们需要等到该视图布局完毕后才能获取宽度
           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();
           final int screenHeight = Math.round(displayMetrics.heightPixels / displayMetrics.density);
           // 计算广告的宽度，同时考虑广告容器中的内边距。
           int adWidthPixels = mBinding.adContainerView.getWidth();
           if (adWidthPixels == 0) {
               // 如果广告尚未布局，则默认为全屏宽度
               adWidthPixels = displayMetrics.widthPixels;
           }
           final int adWidth = Math.round(adWidthPixels / displayMetrics.density);
           // 确定允许的最大广告高度。以当前值为例。
           final int maxAdHeight = screenHeight / 2;

           return BannerAdSize.inlineSize(this, adWidth, maxAdHeight);
       }

       @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() {
                   // 如果此回调发生在活动被销毁之后，您
                   // 必须调用 destroy 和 return，否则可能会出现内存泄漏。
                   // 注意 `isDestroyed` 是活动上的一个方法。
                   if (isDestroyed() && mBannerAd != null) {
                       mBannerAd.destroy();
                   }
               }

               @Override
               public void onAdFailedToLoad(@NonNull final AdRequestError adRequestError) {
                   // 广告加载失败，出现 AdRequestError。
                   // 强烈建议不要尝试通过 onAdFailedToLoad() 方法加载新广告。
               }

               @Override
               public void onAdClicked() {
                   // 记录广告点击时调用。
               }

               @Override
               public void onLeftApplication() {
                   // 当用户由于点击广告而即将离开应用程序（例如，转到浏览器）时调用。
               }

               @Override
               public void onReturnedToApplication() {
                   // 当用户点击后返回应用程序时调用。
               }

               @Override
               public void onImpression(@Nullable ImpressionData impressionData) {
                   // 记录广告展示次数时调用。
               }
           });
           final AdRequest adRequest = new AdRequest.Builder()
                   // 此处可以使用 AdRequest.Builder 类中的方法来指定各个选项设置。
                   .build();
           bannerAd.loadAd(adRequest);
           return bannerAd;
       }
   }
   ```
{% endlist %}

<!-- source: zh/dev/_includes/ad-attributes.md -->
如果您通过 Adfox 投放广告，则在横幅广告响应后，可以使用 `AdAttributes` 类型的 `adAttributes` 属性从 `BannerAdView` 对象访问 `campaignId`、`bannerId` 和 `placeId` 数据。
<!-- endsource: zh/dev/_includes/ad-attributes.md -->

## 释放资源 {#destroy}

如果在活动生命周期结束后调用回调方法，请通过调用广告对象的 `destroy()` 函数来释放资源：

{% list tabs %}

- Kotlin

   ```kotlin
   private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
       return binding.banner.apply {
           setBannerAdEventListener(object : BannerAdEventListener {
               override fun onAdLoaded() {
                   // 如果此回调发生在活动被销毁之后，您
                   // 必须调用 destroy 和 return，否则可能会出现内存泄漏。
                   // 注意 `isDestroyed` 是活动上的一个方法。
                   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() {
               // 如果此回调发生在活动被销毁之后，您
               // 必须调用 destroy 和 return，否则可能会出现内存泄漏。
               // 注意 `isDestroyed` 是活动上的一个方法。
               if (isDestroyed() && mBannerAd != null) {
                   mBannerAd.destroy();
               }
           }
           ...
       });
       ...
       return bannerAd;
   }
   ```
{% endlist %}

## 测试自适应内联横幅集成 {#test}

<!-- source: zh/dev/_includes/test-android-inline-banner.md -->
### 使用演示广告单元进行广告测试 {#demo-blocks}

使用测试广告来检查您的自适应内嵌横幅广告集成和应用本身。为了确保每次广告请求都能返回测试广告，您可以使用一个特殊的演示广告版位 ID。

演示广告单元 ID：`demo-banner-yandex`.

{% note warning %}

在应用商店发布应用前，请务必将演示广告版位 ID 替换为您在 Yandex Advertising Network 接口中获取的真实 ID。

{% endnote %}

有关所有可用演示广告版位 ID 的列表，请参阅[用于测试的演示广告单元](https://ads.yandex.com/helpcenter/zh/dev/android/demo-blocks.md)。

### 测试广告集成 {#test-int}

您可以使用 SDK 的内置分析工具检查自适应内嵌横幅广告是否已正确集成。日志中将显示包含测试结果的详细报告。

要查看报告，请在 Android 应用调试工具 [Logcat](https://developer.android.com/studio/command-line/logcat) 中搜索关键词“YandexAds”。

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

如果集成成功，将返回以下消息：
```bash
adb logcat -v brief '*:S YandexAds'
mobileads$ adb logcat -v brief '*:S YandexAds'
I/YandexAds(13719): [Integration] Ad type banner was integrated successfully
```

如果存在任何横幅广告集成问题，您将收到详细的问题报告和故障排除建议。
<!-- endsource: zh/dev/_includes/test-android-inline-banner.md -->

## 其他资源 {#resources}

* <!-- source: zh/dev/_includes/github-pubdev-links.md -->
  [GitHub](https://github.com/yandexmobile/yandex-ads-sdk-android) 链接。
  <!-- endsource: zh/dev/_includes/github-pubdev-links.md -->

