You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Admob Banner广告截断/拉伸:如何适配全屏正常显示?

解决Admob Banner广告适配全屏宽度且无拉伸/截断的问题

问题描述

使用Admob Banner广告时遇到以下问题:

  • 使用AdSize.banner时,广告组件无法占满屏幕宽度,但广告内容显示正常;
  • 使用AdSize.fullBanner时,广告会被拉伸,内容出现变形。

需要实现横幅广告适配屏幕全屏宽度,同时保证广告内容无截断、无拉伸。

用户当前代码

class _AdBannerState extends State<AdBanner> {
  BannerAd? _inlineAdaptiveAd;
  bool _isLoaded = false;
  AdSize? _finalSize;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _loadAd();
  }

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

    // Get an inline adaptive size for the current orientation.
    AdSize size = AdSize.fullBanner;

    _inlineAdaptiveAd = BannerAd(
      adUnitId: AdHelper.bannerAdUnitId,
      size: size,
      request: const AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) async {
          debugPrint('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.
          BannerAd bannerAd = (ad as BannerAd);
          _finalSize = await bannerAd.getPlatformAdSize();
          // if (size == null) {
          //   debugPrint(
          //       'Error: getPlatformAdSize() returned null for $bannerAd');
          //   return;
          // }

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

  @override
  Widget build(BuildContext context) {
    return (_inlineAdaptiveAd != null && _isLoaded && _finalSize != null)
        ? Expanded(
            child: SizedBox(
                width: _finalSize!.width.toDouble(),
                height: _finalSize!.height.toDouble(),
                child: AdWidget(
                  ad: _inlineAdaptiveAd!,
                )))
        : const SizedBox(
            width: 0,
            height: 0,
          );
  }

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

    super.dispose();
  }
}

解决方案:使用自适应横幅广告

要实现全屏宽度适配且内容正常,需要使用内联自适应横幅广告(Inline Adaptive Banner),它会根据屏幕宽度自动调整广告的高度和内容布局,避免拉伸或截断。

具体修改步骤:

  1. 获取屏幕可用宽度并创建自适应尺寸
    在_loadAd方法中,替换固定的AdSize.fullBanner,改为基于屏幕宽度生成自适应尺寸:

    void _loadAd() async {
      await _inlineAdaptiveAd?.dispose();
      setState(() {
        _inlineAdaptiveAd = null;
        _isLoaded = false;
      });
    
      // 获取屏幕可用宽度(减去左右安全区域)
      final mediaQuery = MediaQuery.of(context);
      final availableWidth = mediaQuery.size.width - mediaQuery.padding.left - mediaQuery.padding.right;
      // 创建自适应横幅尺寸,第二个参数为最小高度(设为0让广告自动适配)
      AdSize size = AdSize.getInlineAdaptiveBannerAdSize(availableWidth.toInt(), 0);
    
      _inlineAdaptiveAd = BannerAd(
        adUnitId: AdHelper.bannerAdUnitId,
        size: size,
        request: const AdRequest(),
        listener: BannerAdListener(
          onAdLoaded: (Ad ad) async {
            debugPrint('Inline adaptive banner loaded: ${ad.responseInfo}');
            BannerAd bannerAd = (ad as BannerAd);
            _finalSize = await bannerAd.getPlatformAdSize();
            if (_finalSize == null) {
              debugPrint('Error: getPlatformAdSize() returned null for $bannerAd');
              return;
            }
            setState(() {
              _inlineAdaptiveAd = bannerAd;
              _isLoaded = true;
            });
          },
          onAdFailedToLoad: (Ad ad, LoadAdError error) {
            debugPrint('Inline adaptive banner failedToLoad: $error');
            ad.dispose();
          },
        ),
      );
      await _inlineAdaptiveAd!.load();
    }
    
  2. 调整布局,避免强制拉伸
    在build方法中,移除Expanded(它会强制占用父组件剩余空间,导致广告拉伸),直接用SizedBox将宽度设为屏幕宽度,高度使用广告加载后返回的实际高度:

    @override
    Widget build(BuildContext context) {
      return (_inlineAdaptiveAd != null && _isLoaded && _finalSize != null)
          ? SizedBox(
              width: MediaQuery.of(context).size.width,
              height: _finalSize!.height.toDouble(),
              child: AdWidget(ad: _inlineAdaptiveAd!),
            )
          : const SizedBox(width: 0, height: 0);
    }
    

原理说明

  • 自适应横幅广告会根据你提供的屏幕宽度,请求最匹配的广告尺寸,广告内容会自动适配该宽度,不会出现拉伸或截断;
  • 加载完成后获取的_finalSize是广告的实际高度,用这个高度设置容器,能保证广告内容完整显示;
  • 移除Expanded避免了强制拉伸广告组件,让广告保持自身的合理比例。

内容的提问来源于stack exchange,提问作者Patola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:23:26