Skip to content
New issue

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

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

Already on GitHub? # to your account

Support passing custom gesture recognizers to AdWidget #1215

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions packages/google_mobile_ads/lib/src/ad_containers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -645,17 +645,28 @@ abstract class AdWithoutView extends Ad {
/// (e.g. [BannerAd] and [NativeAd]) and allows them to be added to the Flutter
/// widget tree.
///
/// Optionally, you can provide [gestureRecognizers] to enable custom gesture
/// interactions with the ad content. For example, this can allow users to
/// swipe or perform other gestures based on your app's requirements.
///
/// Must call `load()` first before showing the widget. Otherwise, a
/// [PlatformException] will be thrown.
class AdWidget extends StatefulWidget {
/// Default constructor for [AdWidget].
///
/// [ad] must be loaded before this is added to the widget tree.
const AdWidget({Key? key, required this.ad}) : super(key: key);
const AdWidget({
Key? key,
required this.ad,
this.gestureRecognizers,
}) : super(key: key);

/// Ad to be displayed as a widget.
final AdWithView ad;

/// Gesture recognizers to enable custom interactions with ads
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;

@override
_AdWidgetState createState() => _AdWidgetState();
}
Expand Down Expand Up @@ -714,7 +725,8 @@ class _AdWidgetState extends State<AdWidget> {
(BuildContext context, PlatformViewController controller) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
gestureRecognizers: widget.gestureRecognizers ??
const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
Expand All @@ -736,6 +748,7 @@ class _AdWidgetState extends State<AdWidget> {
viewType: '${instanceManager.channel.name}/ad_widget',
creationParams: instanceManager.adIdFor(widget.ad),
creationParamsCodec: StandardMessageCodec(),
gestureRecognizers: widget.gestureRecognizers,
);
}
}
Expand Down
40 changes: 40 additions & 0 deletions packages/google_mobile_ads/test/ad_containers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/src/ad_instance_manager.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
Expand Down Expand Up @@ -412,6 +413,45 @@ void main() {
}
});

testWidgets('passes gestureRecognizers to PlatformView on iOS',
(WidgetTester tester) async {
final gestureRecognizers = <Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(() => PanGestureRecognizer()),
Factory<OneSequenceGestureRecognizer>(() => TapGestureRecognizer()),
};

final NativeAd ad = NativeAd(
adUnitId: 'test-ad-unit',
factoryId: '0',
listener: NativeAdListener(),
request: AdRequest(),
);

await ad.load();

debugDefaultTargetPlatformOverride = TargetPlatform.iOS;

await tester.pumpWidget(
MaterialApp(
home: Material(
child: AdWidget(
ad: ad,
gestureRecognizers: gestureRecognizers,
),
),
),
);

final uiKitViewFinder = find.byType(UiKitView);
expect(uiKitViewFinder, findsOneWidget);

final uiKitView = tester.widget<UiKitView>(uiKitViewFinder);
expect(uiKitView.gestureRecognizers, gestureRecognizers);

debugDefaultTargetPlatformOverride = null;
await ad.dispose();
});

test('load show rewarded', () async {
RewardedAd? rewarded;
AdRequest request = AdRequest();
Expand Down