googleads / googleads-mobile-flutter

A Flutter plugin for the Google Mobile Ads SDK
Apache License 2.0
343 stars 285 forks source link

2 page ad #912

Closed batuhansavas-yilmaz closed 1 year ago

batuhansavas-yilmaz commented 1 year ago

Hello from Turkey. I added admob ads to my Flutter application.There is an ad on each page in the 2-page application and there is such a situation that the ad on the main page stays open even if the page changes. But the ad on the 2nd page only opens when the page is changed. Is there a mistake here, is there a problem or does it work like this? I also examined the documentation and there is nothing missing in my code.

darshankawar commented 1 year ago

@batuhansavas-yilmaz Can you provide a runnable code sample along with flutter doctor -v that shows the reported behavior ? You can also attach a short video showing the behavior you are seeing.

batuhansavas-yilmaz commented 1 year ago

My codes :

late BannerAd? _bannerAd;
  bool _isBannerAdReady = false;
  void _loadBannerAd() {
    _bannerAd = BannerAd(
      adUnitId: mainReklam,
      size: AdSize.banner,
      request: AdRequest(keywords: [
        'flutter',
        'invoice',
        'tax',
        'tools',
        'solver',
        'aquarium',
        'fish',
        "car",
        "horse",
        "power",
        "hp"
      ]),
      listener: BannerAdListener(
        onAdLoaded: (_) {
          setState(() {
            _isBannerAdReady = true;
          });
        },
        onAdFailedToLoad: (ad, error) {
          _bannerAd!.dispose();
        },
      ),
    );

    _bannerAd!.load();
  }

  @override
  void initState() {
    super.initState();
    _loadBannerAd();
  }

  void dispose() {
    super.dispose();
    _bannerAd!.dispose();
  }

  Widget build(BuildContext context) {
    return Scaffold(
        extendBody: true,
        appBar: AppBar(
          title: Text(
            "HesapMatik",
          ),
          centerTitle: true,
        ),
        body: GridView.count(
          childAspectRatio: 0.9,
          primary: true,
          crossAxisSpacing: 30,
          mainAxisSpacing: 10,
          padding: EdgeInsets.all(30.0),
          crossAxisCount: 2,
          children: [
            GorevButton(
              logo: "assets/percentage.png",
              altisim: "KDV \nHesaplayıcısı",
              sayfaismi: '/kdv',
            ),
            GorevButton(
              logo: "assets/car.png",
              altisim: "Binek Araç Gider",
              sayfaismi: '/binekarac',
            ),
            GorevButton(
              logo: "assets/aquarium.png",
              altisim: "Akvaryum",
              sayfaismi: '/akvaryum',
            ),
            GorevButton(
              logo: "assets/zraporu.png",
              altisim: "Eksik Z Raporu Kurtarıcı",
              sayfaismi: '/zraporu',
            ),
            GorevButton(
              logo: "assets/love.png",
              altisim: "Vücut Kitle Endeksi",
              sayfaismi: '/vucut',
            ),
            GorevButton(
              logo: "assets/horse-power.png",
              altisim: "kW ⇄ hp",
              sayfaismi: '/beygir',
            ),
            GorevButton(
              logo: "assets/commission.png",
              altisim: "Komisyon",
              sayfaismi: '/komisyon',
            ),
            GorevButton(
              logo: "assets/petrol.png",
              altisim: "Yakıt Tüketimi",
              sayfaismi: '/yakit',
            ),
            SizedBox(),
            SizedBox(),
            SizedBox(),
            SizedBox(),
          ],
        ),
        bottomNavigationBar: Container(
          decoration: BoxDecoration(boxShadow: [
            BoxShadow(
              color: Colors.white.withOpacity(0.9),
              spreadRadius: 20,
              blurRadius: 13,
              offset: const Offset(0, 20),
            )
          ]),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              _isBannerAdReady
                  ? SizedBox(
                      width: _bannerAd!.size.width.toDouble(),
                      height: _bannerAd!.size.height.toDouble(),
                      child: AdWidget(ad: _bannerAd!))
                  : SizedBox(
                      width: _bannerAd!.size.width.toDouble(),
                      height: _bannerAd!.size.height.toDouble(),
                    ),
              const SizedBox(
                height: 20,
              ),
              Container(
                decoration: const BoxDecoration(color: Colors.blue, boxShadow: [
                  BoxShadow(offset: Offset(-0.00, -0.10), blurRadius: 0.3)
                ]),
                height: 1,
              ),
            ],
          ),
        ));

Flutter doctor -v


[√] Flutter (Channel stable, 3.13.2, on Microsoft Windows [Version 10.0.19045.3324], locale tr-TR)
    • Flutter version 3.13.2 on channel stable at C:\src\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ff5b5b5fa6 (7 days ago), 2023-08-24 08:12:28 -0500
    • Engine revision b20183e040
    • Dart version 3.1.0
    • DevTools version 2.25.0

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at C:\Android\Sdk
    • Platform android-UpsideDownCakePrivacySandbox, build-tools 34.0.0
    • ANDROID_HOME = C:\Android\Sdk
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694)
    • All Android licenses accepted.

[√] Android Studio (version 2022.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694)

[√] VS Code (version 1.81.1)
    • VS Code at C:\Users\Barış\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.70.0

[√] Connected device (2 available)
    • SM M105G (mobile) • 5200381bd465464b   • android-arm   • Android 10 (API 29)
    • M2101K6G (mobile) • 192.168.1.34:38557 • android-arm64 • Android 13 (API 33)

[√] Network resources
    • All expected network resources are available.

Video :

https://github.com/googleads/googleads-mobile-flutter/assets/71197619/24046114-0636-4a15-88ed-6c685d620873

@darshankawar

batuhansavas-yilmaz commented 1 year ago

@darshankawar Have you been able to examine it?

batuhansavas-yilmaz commented 1 year ago

@darshankawar sir ?

darshankawar commented 1 year ago

@batuhansavas-yilmaz What is GorevButton ? Is this a custom button ? Can you replace it with ElevatedButton or TextButton ? Also, please provide us a runnable code sample that we can directly copy paste and run, mostly using just out-of-box widgets without any third party package code implementation.

batuhansavas-yilmaz commented 1 year ago

okey, this is example :

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  MobileAds.instance.initialize();
  runApp(const MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatefulWidget {
  const FirstRoute({super.key});

  @override
  State<FirstRoute> createState() => _FirstRouteState();
}

class _FirstRouteState extends State<FirstRoute> {
  late BannerAd? _bannerAd;

  bool _isBannerAdReady = false;

  void _loadBannerAd() {
    _bannerAd = BannerAd(
      adUnitId: 'ca-app-pub-3940256099942544/6300978111',
      size: AdSize.banner,
      request: AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (_) {
          setState(() {
            _isBannerAdReady = true;
          });
        },
        onAdFailedToLoad: (ad, error) {
          _bannerAd!.dispose();
        },
      ),
    );

    _bannerAd!.load();
  }

  @override
  void initState() {
    super.initState();
    _loadBannerAd();
  }

  void dispose() {
    super.dispose();
    _bannerAd!.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Route'),
      ),
      body: Center(
        child: ElevatedButton(
          child: const Text('Open route'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const SecondRoute()),
            );
          },
        ),
      ),
      bottomNavigationBar: _isBannerAdReady
          ? SizedBox(
              width: _bannerAd!.size.width.toDouble(),
              height: _bannerAd!.size.height.toDouble(),
              child: AdWidget(ad: _bannerAd!))
          : SizedBox(
              width: _bannerAd!.size.width.toDouble(),
              height: _bannerAd!.size.height.toDouble(),
            ),
    );
  }
}

class SecondRoute extends StatefulWidget {
  const SecondRoute({super.key});

  @override
  State<SecondRoute> createState() => _SecondRouteState();
}

class _SecondRouteState extends State<SecondRoute> {
  late BannerAd? _bannerAd;

  bool _isBannerAdReady = false;

  void _loadBannerAd() {
    _bannerAd = BannerAd(
      adUnitId: 'ca-app-pub-3940256099942544/6300978111',
      size: AdSize.banner,
      request: AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (_) {
          setState(() {
            _isBannerAdReady = true;
          });
        },
        onAdFailedToLoad: (ad, error) {
          _bannerAd!.dispose();
        },
      ),
    );

    _bannerAd!.load();
  }

  @override
  void initState() {
    super.initState();
    _loadBannerAd();
  }

  void dispose() {
    super.dispose();
    _bannerAd!.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Route'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
      bottomNavigationBar: _isBannerAdReady
          ? SizedBox(
              width: _bannerAd!.size.width.toDouble(),
              height: _bannerAd!.size.height.toDouble(),
              child: AdWidget(ad: _bannerAd!))
          : SizedBox(
              width: _bannerAd!.size.width.toDouble(),
              height: _bannerAd!.size.height.toDouble(),
            ),
    );
  }
}
batuhansavas-yilmaz commented 1 year ago

@jjliu15 @darshankawar Can someone answer?

batuhansavas-yilmaz commented 1 year ago

@darshankawar

huycozy commented 1 year ago

@batuhansavas-yilmaz Thanks for your update with minimal sample code.

To explain the behavior you observed, please take a look at your navigation logic. You are calling _bannerAd!.dispose() on the first widget's dispose() method but you are navigating to the second page with Navigator.push. This explains why the banner ad on the first page remains the same. In case you want to refresh the ad on this page, you can use pushReplacement when navigating to the second page; the first page then will be removed from navigation stack, and dispose() is invoked.

For the ad on the second page, it's refreshed because you load a new ad in initState() of the page. Then new ad will be requested from AdMob/Ad Manager.

Closing the issue as intended behavior.

batuhansavas-yilmaz commented 1 year ago

This is not a correct usage because when you move from one page to another page with pushReplacement, it deletes the first page and it is impossible to return to that page in the application.

huycozy commented 1 year ago

Using pushReplacement as an alternative to push is just an example to invoke widget's dispose method. That being said, ad's dispose will work if you call it properly. Instead of using pushReplacement, you can call ad's dispose before navigating to the 2nd page. And you will need to re-initialize the ad when you return to the 1st page from the 2nd page. See support channels like StackOverflow for solutions if any.

batuhansavas-yilmaz commented 1 year ago

I already asked you because I couldn't find a solution. Was I wrong to ask you as the developer of the package or should I have looked at stackoverflow(!)

huycozy commented 1 year ago

Hi @batuhansavas-yilmaz I'm not sure which is your expected result (keeping ad persists or refreshing it when navigating), but the behavior you observed (from your initial sample code) is intentional.

In short, if you want to keep ad persists, don't call ad's dispose when the widget/page is disposed. Otherwise, let's call ad's dispose and load properly when navigating the pages.

Since the issue is related to your implementation, you should ask this in the support channel like StackOverflow.

batuhansavas-yilmaz commented 1 year ago

Yes, you are right, the help I need from you is how can I refresh the ad while browsing? I tried all kinds of codes but I couldn't do it.