Skip to content

Commit

Permalink
Add flag to AdWidget that lets you opt out of visibility detector wor…
Browse files Browse the repository at this point in the history
…karound (#762)

* Adds a flag to AdWidget that lets you opt out of visibility detector workaround added in #610.
  • Loading branch information
jjliu15 committed Jan 31, 2023
1 parent 7c39d4f commit 4d929e2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/google_mobile_ads/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* `NativeAd` has a new optional parameter, `nativeTemplateStyle` of type `NativeTemplateStyle`.
If provided, the plugin will inflate and style a platform native ad view for you, instead of
requiring you to write and register a NativeAdFactory (android) or FLTNativeAdFactory (iOS).
* Adds a new flag, AdWidget.optOutOfVisibilityDetectorWorkaround. Setting this to true
lets you opt out of the fix added for https://github.com/googleads/googleads-mobile-flutter/issues/580,
which was resolved in Flutter 3.7.0.

## 2.3.0
* Updates GMA iOS dependency to 9.13
Expand Down
14 changes: 12 additions & 2 deletions packages/google_mobile_ads/lib/src/ad_containers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,16 @@ abstract class AdWithoutView extends Ad {
/// Must call `load()` first before showing the widget. Otherwise, a
/// [PlatformException] will be thrown.
class AdWidget extends StatefulWidget {
/// Opt out of the visibility detector workaround.
///
/// As a workaround for
/// https://github.com/googleads/googleads-mobile-flutter/issues/580,
/// we wait for the widget to get displayed once before attaching
/// the platform view.
///
/// Set this flag to true if you are building with Flutter 3.7.0 or higher.
static bool optOutOfVisibilityDetectorWorkaround = false;

/// Default constructor for [AdWidget].
///
/// [ad] must be loaded before this is added to the widget tree.
Expand Down Expand Up @@ -684,8 +694,8 @@ class _AdWidgetState extends State<AdWidget> {
// https://github.com/googleads/googleads-mobile-flutter/issues/580,
// where impressions are erroneously fired due to how platform views are
// rendered.
// TODO (jjliu15): Remove this after the flutter issue is resolved.
if (_firstVisibleOccurred) {
if (_firstVisibleOccurred ||
AdWidget.optOutOfVisibilityDetectorWorkaround) {
return PlatformViewLink(
viewType: '${instanceManager.channel.name}/ad_widget',
surfaceFactory:
Expand Down
53 changes: 52 additions & 1 deletion packages/google_mobile_ads/test/ad_containers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,9 @@ void main() {
debugDefaultTargetPlatformOverride = null;
});

testWidgets('Build ad widget Android', (WidgetTester tester) async {
testWidgets('Build ad widget Android, visibility detector workaround on',
(WidgetTester tester) async {
AdWidget.optOutOfVisibilityDetectorWorkaround = false;
debugDefaultTargetPlatformOverride = TargetPlatform.android;
// Create a loaded ad
final ad = NativeAd(
Expand Down Expand Up @@ -382,6 +384,55 @@ void main() {
debugDefaultTargetPlatformOverride = null;
});

testWidgets('Build ad widget Android, visibility detector opted out',
(WidgetTester tester) async {
AdWidget.optOutOfVisibilityDetectorWorkaround = true;
debugDefaultTargetPlatformOverride = TargetPlatform.android;
// Create a loaded ad
final ad = NativeAd(
adUnitId: 'test-ad-unit',
factoryId: '0',
listener: NativeAdListener(),
request: AdRequest(),
);
await ad.load();

// Render ad in a scrolling view
VisibilityDetectorController.instance.updateInterval = Duration.zero;
await tester.pumpWidget(
MaterialApp(
home: Material(
child: SingleChildScrollView(
child: Column(
key: UniqueKey(),
children: [
SizedBox.fromSize(size: Size(200, 1000)),
Container(
height: 200,
width: 200,
child: AdWidget(ad: ad),
),
],
),
),
),
),
);
await tester.pumpAndSettle();

// VisibilityRender should not be in the UI
final visibilityDetectors =
tester.widgetList(find.byType(VisibilityDetector));
expect(visibilityDetectors.isEmpty, true);

final platformViewLink = tester.widget(find.byType(PlatformViewLink));
expect(platformViewLink, isNotNull);

// Reset platform override
await ad.dispose();
debugDefaultTargetPlatformOverride = null;
});

testWidgets('warns when ad has not been loaded',
(WidgetTester tester) async {
final NativeAd ad = NativeAd(
Expand Down

0 comments on commit 4d929e2

Please sign in to comment.