内嵌自适应横幅广告

自适应横幅广告是新一代自适应广告,可针对每台设备优化广告尺寸,从而最大限度地提升广告效果。自适应横幅广告在仅支持固定高度的固定尺寸横幅广告的基础上进行了改进,可让开发者指定广告宽度,并据此确定最佳广告尺寸。

为了选择最佳广告尺寸,内嵌自适应横幅广告会使用最大高度而非固定高度。这样做有助于提升广告效果。

何时使用内嵌自适应横幅广告

与锚定自适应横幅广告相比,内嵌自适应横幅广告是一种更大、更高的横幅广告。它们的高度可变,与设备屏幕一样高。

应放置在滚动内容中,例如:

前提条件

准备工作

在应用中植入自适应横幅广告时,请注意以下几点:

  • 确保您使用的是最新版 Google 移动广告 SDK;如果您使用的是中介功能,请确保您使用的是最新版中介适配器。

  • 内嵌自适应横幅广告的尺寸经过专门设计,占满可用宽度时效果最佳。在大多数情况下,这里指的是所用设备的屏幕全宽。请务必考虑适用的安全区域。

  • 您可能需要更新或创建新订单项来使用自适应尺寸。 了解详情

  • 获取广告尺寸的方法如下

    • AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width)
    • AdSize.getLandscapeInlineAdaptiveBannerAdSize(int width)
    • AdSize.getPortraitInlineAdaptiveBannerAdSize(int width)
    • AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight)
  • 使用内嵌自适应横幅广告 API 时,Google 移动广告 SDK 会返回具有指定宽度和内嵌标记的 AdSize。高度为零或 maxHeight,具体取决于您使用的 API。广告的实际高度在返回时可用。

  • 内嵌自适应横幅广告适合放置在可滚动的内容中。横幅广告可与设备屏幕一样高,也可以受最大高度限制,具体取决于 API。

实现

若要植入简单的内嵌自适应横幅广告,请按照以下步骤操作。

  1. 获取内嵌自适应横幅广告尺寸。您获取的尺寸将用于请求自适应横幅广告。要获取自适应广告尺寸,请务必执行以下操作:
    1. 获取所用设备的宽度(以密度无关像素为单位),或者自行设置宽度(如果您不想使用屏幕的全宽)。您可以使用 MediaQuery.of(context) 获取屏幕宽度。
    2. 针对广告尺寸类使用相应的静态方法(例如 AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width)),获取适用于当前屏幕方向的内嵌自适应 AdSize 对象。
    3. 如果您想限制横幅广告的高度,可以使用静态方法 AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight)
  2. 使用广告单元 ID、自适应广告尺寸和广告请求对象创建 AdManagerBannerAd 对象。
  3. 加载广告。
  4. onAdLoaded 回调中,使用 AdManagerBannerAd.getPlatformAdSize() 获取更新后的平台广告尺寸,并更新 AdWidget 容器高度。

代码示例

下面的 widget 示例会加载内嵌自适应横幅广告以适应屏幕宽度,且考虑到边衬区:

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

/// This example demonstrates inline adaptive banner ads.
///
/// Loads and shows an inline adaptive banner ad in a scrolling view,
/// and reloads the ad when the orientation changes.
class InlineAdaptiveExample extends StatefulWidget {
  @override
  _InlineAdaptiveExampleState createState() => _InlineAdaptiveExampleState();
}

class _InlineAdaptiveExampleState extends State<InlineAdaptiveExample> {
  static const _insets = 16.0;
  AdManagerBannerAd? _inlineAdaptiveAd;
  bool _isLoaded = false;
  AdSize? _adSize;
  late Orientation _currentOrientation;

  double get _adWidth => MediaQuery.of(context).size.width - (2 * _insets);

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _currentOrientation = MediaQuery.of(context).orientation;
    _loadAd();
  }

  void _loadAd() async {
    await _inlineAdaptiveAd?.dispose();
    setState(() {
      _inlineAdaptiveAd = null;
      _isLoaded = false;
    });

    // Get an inline adaptive size for the current orientation.
    AdSize size = AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(
        _adWidth.truncate());

    _inlineAdaptiveAd = AdManagerBannerAd(
      // TODO: replace with your own ad unit.
      adUnitId: '<your-ad-unit>',
      size: size,
      request: AdManagerAdRequest(),
      listener: AdManagerBannerAdListener(
        onAdLoaded: (Ad ad) async {
          print('Inline adaptive banner loaded: ${ad.responseInfo}');

          // After the ad is loaded, get the platform ad size and use it to
          // update the height of the container. This is necessary because the
          // height can change after the ad is loaded.
          AdManagerBannerAd bannerAd = (ad as AdManagerBannerAd);
          final AdSize? size = await bannerAd.getPlatformAdSize();
          if (size == null) {
            print('Error: getPlatformAdSize() returned null for $bannerAd');
            return;
          }

          setState(() {
            _inlineAdaptiveAd = bannerAd;
            _isLoaded = true;
            _adSize = size;
          });
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          print('Inline adaptive banner failedToLoad: $error');
          ad.dispose();
        },
      ),
    );
    await _inlineAdaptiveAd!.load();
  }

  /// Gets a widget containing the ad, if one is loaded.
  ///
  /// Returns an empty container if no ad is loaded, or the orientation
  /// has changed. Also loads a new ad if the orientation changes.
  Widget _getAdWidget() {
    return OrientationBuilder(
      builder: (context, orientation) {
        if (_currentOrientation == orientation &&
            _inlineAdaptiveAd != null &&
            _isLoaded &&
            _adSize != null) {
          return Align(
              child: Container(
            width: _adWidth,
            height: _adSize!.height.toDouble(),
            child: AdWidget(
              ad: _inlineAdaptiveAd!,
            ),
          ));
        }
        // Reload the ad if the orientation changes.
        if (_currentOrientation != orientation) {
          _currentOrientation = orientation;
          _loadAd();
        }
        return Container();
      },
    );
  }

  @override
  Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(
        title: Text('Inline adaptive banner example'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: _insets),
          child: ListView.separated(
            itemCount: 20,
            separatorBuilder: (BuildContext context, int index) {
              return Container(
                height: 40,
              );
            },
            itemBuilder: (BuildContext context, int index) {
              if (index == 10) {
                return _getAdWidget();
              }
              return Text(
                'Placeholder text',
                style: TextStyle(fontSize: 24),
              );
            },
          ),
        ),
      ));

  @override
  void dispose() {
    super.dispose();
    _inlineAdaptiveAd?.dispose();
  }
}