Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Banner is re-created/re-loaded with each Navigator push()/pop() #18

Closed
kestasb opened this issue Feb 16, 2019 · 27 comments · Fixed by #129
Closed

Banner is re-created/re-loaded with each Navigator push()/pop() #18

kestasb opened this issue Feb 16, 2019 · 27 comments · Fixed by #129
Labels
enhancement New feature or request help wanted Extra attention is needed more info required An issue was created with enough information to debug.

Comments

@kestasb
Copy link

kestasb commented Feb 16, 2019

Banner is reloaded with each Navigator push()/pop(), both onBannerCreated and AdmobAdEvent.loaded are called even the banner is a child of a const StalessWidget, whose build() method isn't called.
Admob guidelines does not recommend to refresh banner manually.
Is it possible to avoid this behaviour?

@inartin
Copy link

inartin commented Apr 18, 2019

Have you found any solutions to that ? I have the same problem.
Also most of the time I don't see any ads at all, I thing that's because it is rebuilded on every move, scroll ...

--Update
Just updated to 0.2.0 and now ads are shown as expected :)

@kmcgill88 kmcgill88 added enhancement New feature or request help wanted Extra attention is needed more info required An issue was created with enough information to debug. labels May 23, 2019
@mmahkamov
Copy link

I was having a similar issue when the AdmobBanner widget was used in a ListView.

I wrapped AdmobBanner into a custom AdmobBannerWrapper stateful widget with AutomaticKeepAliveClientMixin - the issue was resolved.

@mmahkamov
Copy link

mmahkamov commented May 30, 2019

I think the AdmobBanner widget should be implemented with AutomaticKeepAliveClientMixin out of the box because redundant reloading of banners should be avoided (because it generates false impressions?). One could optionally pass the value for the wantKeepAlive property in the constructor.

@sumitgohil
Copy link

@mmahkamov Can you help me out? How should be this Implemented? How did you resolve the issue?

@mmahkamov
Copy link

@mmahkamov Can you help me out? How should be this Implemented? How did you resolve the issue?

I've just wrapped AdmobBanner inside a stateful widget which implements AutomaticKeepAliveClientMixin:

class AdmobBannerWrapper extends StatefulWidget {
  final String adUnitId;
  final AdmobBannerSize adSize;

  AdmobBannerWrapper({
    Key key,
    this.adUnitId, this.adSize
  }) : super(key: key);

  @override
  AdmobBannerWrapperState createState() => AdmobBannerWrapperState();
}

class AdmobBannerWrapperState extends State<AdmobBannerWrapper> with AutomaticKeepAliveClientMixin {
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    return AdmobBanner(
            adUnitId: widget.adUnitId, 
            adSize: widget.adSize
    );
  }
}

@sumitgohil
Copy link

@mmahkamov Looks like this doesn't work for me. The Banner ad still keeps reloading while popping view.

@kyleorin
Copy link

@mmahkamov I tried your method above, it seems the reloading doesn't stop although a new error appeared:

<Google> Cannot find an ad network adapter with the name(s): com.google.DummyAdapter. Remember to link all required ad network adapters and SDKs, and set -ObjC in the 'Other Linker Flags' setting of your build target.

(using the test banner ad)

also, I called the widget like so:

AdmobBannerWrapper(
                  adUnitId: 'ca-app-pub-3940256099942544/2934735716',
                  adSize: AdmobBannerSize.BANNER,
                ),

@mmahkamov
Copy link

@mmahkamov Looks like this doesn't work for me. The Banner ad still keeps reloading while popping view.

Are you using FutureBuilder by any chance?

@narayanansampath
Copy link

@mmahkamov Can you help me out? How should be this Implemented? How did you resolve the issue?

I've just wrapped AdmobBanner inside a stateful widget which implements AutomaticKeepAliveClientMixin:

class AdmobBannerWrapper extends StatefulWidget {
  final String adUnitId;
  final AdmobBannerSize adSize;

  AdmobBannerWrapper({
    Key key,
    this.adUnitId, this.adSize
  }) : super(key: key);

  @override
  AdmobBannerWrapperState createState() => AdmobBannerWrapperState();
}

class AdmobBannerWrapperState extends State<AdmobBannerWrapper> with AutomaticKeepAliveClientMixin {
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    return AdmobBanner(
            adUnitId: widget.adUnitId, 
            adSize: widget.adSize
    );
  }
}

This fix didn't work for me and I'm not using FutureBuilder too. Please help :(

@nimish1995
Copy link

no working! Any solution? in every refresh of the list it shows blank blink which not looks good. and is there any way to preload the banner and show only if it's loaded??

@mmahkamov
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

@nimish1995
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

Can you share the code? How can do that?

@narayanansampath
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

I changed the container color to white as my screen background is white but the ad container still displays black color.

@nimish1995
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

I changed the container color to white as my screen background is white but the ad container still displays black color.

same here

@mmahkamov
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

Can you share the code? How can do that?

You can get the idea from the following patch or just git apply it.

From 7a8e1be7ae027626fc77db41386595268707119f Mon Sep 17 00:00:00 2001
From: Muzaffar Mahkamov <muzaffar@mahkamov.com>
Date: Sun, 30 Jun 2019 12:01:49 +0500
Subject: [PATCH] * making AdmobBanner background transparent

---
 .../com/shatsy/admobflutter/AdmobBanner.kt    |  1 +
 .../shatsy/admobflutter/TransparentView.kt    | 25 +++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt

diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
index 7319607..8077f89 100644
--- a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
@@ -44,6 +44,7 @@ class AdmobBanner(context: Context, messenger: BinaryMessenger, id: Int, args: H
   }
 
   override fun getView(): View {
+    adView.makeWindowTransparent()
     return adView
   }
 
diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
new file mode 100644
index 0000000..0842c10
--- /dev/null
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
@@ -0,0 +1,25 @@
+package com.shatsy.admobflutter
+
+import android.view.View
+import android.view.Window
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+
+public fun View.makeWindowTransparent() {
+  this.post {
+    try {
+      var parent = this.parent ?: return@post
+      while (parent?.parent != null) {
+        parent = parent.parent
+      }
+      val decorView = parent.javaClass.getDeclaredMethod("getView").invoke(parent)
+      val windowField = decorView.javaClass.getDeclaredField("mWindow")
+      windowField.isAccessible = true
+      val window = windowField.get(decorView) as Window
+      windowField.isAccessible = false
+      window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+    } catch (e: Exception) {
+      // log it
+    }
+  }
+}
\ No newline at end of file
-- 
2.20.1

@narayanansampath
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

Can you share the code? How can do that?

You can get the idea from the following patch or just git apply it.

From 7a8e1be7ae027626fc77db41386595268707119f Mon Sep 17 00:00:00 2001
From: Muzaffar Mahkamov <muzaffar@mahkamov.com>
Date: Sun, 30 Jun 2019 12:01:49 +0500
Subject: [PATCH] * making AdmobBanner background transparent

---
 .../com/shatsy/admobflutter/AdmobBanner.kt    |  1 +
 .../shatsy/admobflutter/TransparentView.kt    | 25 +++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt

diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
index 7319607..8077f89 100644
--- a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
@@ -44,6 +44,7 @@ class AdmobBanner(context: Context, messenger: BinaryMessenger, id: Int, args: H
   }
 
   override fun getView(): View {
+    adView.makeWindowTransparent()
     return adView
   }
 
diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
new file mode 100644
index 0000000..0842c10
--- /dev/null
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
@@ -0,0 +1,25 @@
+package com.shatsy.admobflutter
+
+import android.view.View
+import android.view.Window
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+
+public fun View.makeWindowTransparent() {
+  this.post {
+    try {
+      var parent = this.parent ?: return@post
+      while (parent?.parent != null) {
+        parent = parent.parent
+      }
+      val decorView = parent.javaClass.getDeclaredMethod("getView").invoke(parent)
+      val windowField = decorView.javaClass.getDeclaredField("mWindow")
+      windowField.isAccessible = true
+      val window = windowField.get(decorView) as Window
+      windowField.isAccessible = false
+      window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+    } catch (e: Exception) {
+      // log it
+    }
+  }
+}
\ No newline at end of file
-- 
2.20.1

Can you please elaborate on the steps for applying this as patch. Thanks.

@oliverbytes
Copy link

The blink is happening because the background color of the native widget is white by default. You need to patch the native side to make the host view transparent.

Can you share the code? How can do that?

You can get the idea from the following patch or just git apply it.

From 7a8e1be7ae027626fc77db41386595268707119f Mon Sep 17 00:00:00 2001
From: Muzaffar Mahkamov <muzaffar@mahkamov.com>
Date: Sun, 30 Jun 2019 12:01:49 +0500
Subject: [PATCH] * making AdmobBanner background transparent

---
 .../com/shatsy/admobflutter/AdmobBanner.kt    |  1 +
 .../shatsy/admobflutter/TransparentView.kt    | 25 +++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt

diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
index 7319607..8077f89 100644
--- a/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/AdmobBanner.kt
@@ -44,6 +44,7 @@ class AdmobBanner(context: Context, messenger: BinaryMessenger, id: Int, args: H
   }
 
   override fun getView(): View {
+    adView.makeWindowTransparent()
     return adView
   }
 
diff --git a/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
new file mode 100644
index 0000000..0842c10
--- /dev/null
+++ b/android/src/main/kotlin/com/shatsy/admobflutter/TransparentView.kt
@@ -0,0 +1,25 @@
+package com.shatsy.admobflutter
+
+import android.view.View
+import android.view.Window
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+
+public fun View.makeWindowTransparent() {
+  this.post {
+    try {
+      var parent = this.parent ?: return@post
+      while (parent?.parent != null) {
+        parent = parent.parent
+      }
+      val decorView = parent.javaClass.getDeclaredMethod("getView").invoke(parent)
+      val windowField = decorView.javaClass.getDeclaredField("mWindow")
+      windowField.isAccessible = true
+      val window = windowField.get(decorView) as Window
+      windowField.isAccessible = false
+      window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+    } catch (e: Exception) {
+      // log it
+    }
+  }
+}
\ No newline at end of file
-- 
2.20.1

Can you please elaborate on the steps for applying this as patch. Thanks.

I second this. please help us bro... thanks a lot

@kmcgill88
Copy link
Owner

Has anyone in this thread considered doing something like this? #61 (comment)

@oliverbytes
Copy link

#61 (comment)

That is a nice workaround. But I'd rather use firebase_admob for that.

@edeuss
Copy link
Collaborator

edeuss commented Dec 19, 2019

@kestasb Where you able to get a work around for this issue?

@trqalothman
Copy link

Any update/fix for this issue? it is one thing that is holding me back from the new release :(

@benevolent13
Copy link

I was having a similar issue when the AdmobBanner widget was used in a ListView.

I wrapped AdmobBanner into a custom AdmobBannerWrapper stateful widget with AutomaticKeepAliveClientMixin - the issue was resolved.

Doesn't work for me.It gets reloaded everytime setState is called. :(

@erperejildo
Copy link

class AdmobBannerWrapper extends StatefulWidget {
final String adUnitId;
final AdmobBannerSize adSize;

AdmobBannerWrapper({
Key key,
this.adUnitId, this.adSize
}) : super(key: key);

@OverRide
AdmobBannerWrapperState createState() => AdmobBannerWrapperState();
}

class AdmobBannerWrapperState extends State with AutomaticKeepAliveClientMixin {
bool get wantKeepAlive => true;

@OverRide
Widget build(BuildContext context) {
return AdmobBanner(
adUnitId: widget.adUnitId,
adSize: widget.adSize
);
}
}

this didn't work for me

@erperejildo
Copy link

This quite important error has more than a year now

@sumitgohil
Copy link

sumitgohil commented Feb 26, 2020

I am not sure if I've made a solution to this, but it kinda worked for me. I made changed to this long back and I don't really have a track on them. I've also changed channel names and it's done on fork of a previous version of this lib. It might not contain features available in the newer version. I've added this to my repo. If someone could check and see if this works.

https://github.com/sumitgohil/flutter_admob_plugin

@edeuss
Copy link
Collaborator

edeuss commented Feb 27, 2020

@sumitgohil @erperejildo It is in the package but hasn't been updated in the pub.dev

Use this for now:

admob_flutter:
    git:
      url: git://github.com/kmcgill88/admob_flutter.git

@erperejildo
Copy link

@sumitgohil @erperejildo It is in the package but hasn't been updated in the pub.dev

Use this for now:

admob_flutter:
    git:
      url: git://github.com/kmcgill88/admob_flutter.git

I can confirm this, it works.

Let's see when this gets merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed more info required An issue was created with enough information to debug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.