diff --git a/packages/firebase_admob/CHANGELOG.md b/packages/firebase_admob/CHANGELOG.md index 03ca09e32284..7a44bfb131f5 100644 --- a/packages/firebase_admob/CHANGELOG.md +++ b/packages/firebase_admob/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.0+4 + +* Add the ability to horizontally adjust the ads banner location by specifying a pixel offset from the centre. + ## 0.9.0+3 * Update google-services Android gradle plugin to 4.3.0 in documentation and examples. diff --git a/packages/firebase_admob/README.md b/packages/firebase_admob/README.md index 80a1ca5f416e..a7a285249c49 100644 --- a/packages/firebase_admob/README.md +++ b/packages/firebase_admob/README.md @@ -122,6 +122,23 @@ myBanner ..show( // Positions the banner ad 60 pixels from the bottom of the screen anchorOffset: 60.0, + // Positions the banner ad 10 pixels from the center of the screen to the right + horizontalCenterOffset: 10.0, + // Banner Position + anchorType: AnchorType.bottom, + ); +``` + +Ads must be loaded before they're shown. +```dart +myBanner + // typically this happens well before the ad is shown + ..load() + ..show( + // Positions the banner ad 60 pixels from the bottom of the screen + anchorOffset: 60.0, + // Positions the banner ad 10 pixels from the center of the screen to the left + horizontalCenterOffset: -10.0, // Banner Position anchorType: AnchorType.bottom, ); @@ -133,6 +150,7 @@ myInterstitial ..show( anchorType: AnchorType.bottom, anchorOffset: 0.0, + horizontalCenterOffset: 0.0, ); ``` @@ -186,7 +204,6 @@ method. This is just an initial version of the plugin. There are still some limitations: -- Banner ads have limited positioning functionality. They can be positioned at the top or the bottom of the screen and at a logical pixel offset from the edge. - Banner ads cannot be animated into view. - It's not possible to specify a banner ad's size. - There's no support for native ads. diff --git a/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/FirebaseAdMobPlugin.java b/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/FirebaseAdMobPlugin.java index 8fb1fb3e2ec9..62e6fe4befeb 100644 --- a/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/FirebaseAdMobPlugin.java +++ b/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/FirebaseAdMobPlugin.java @@ -151,6 +151,10 @@ private void callShowAd(int id, MethodCall call, Result result) { if (call.argument("anchorOffset") != null) { ad.anchorOffset = Double.parseDouble((String) call.argument("anchorOffset")); } + if (call.argument("horizontalCenterOffset") != null) { + ad.horizontalCenterOffset = + Double.parseDouble((String) call.argument("horizontalCenterOffset")); + } if (call.argument("anchorType") != null) { ad.anchorType = call.argument("anchorType").equals("bottom") ? Gravity.BOTTOM : Gravity.TOP; } diff --git a/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/MobileAd.java b/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/MobileAd.java index 0b3fa19c64f6..a13573194c94 100644 --- a/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/MobileAd.java +++ b/packages/firebase_admob/android/src/main/java/io/flutter/plugins/firebaseadmob/MobileAd.java @@ -28,6 +28,7 @@ abstract class MobileAd extends AdListener { final int id; Status status; double anchorOffset; + double horizontalCenterOffset; int anchorType; enum Status { @@ -44,6 +45,7 @@ private MobileAd(int id, Activity activity, MethodChannel channel) { this.channel = channel; this.status = Status.CREATED; this.anchorOffset = 0.0; + this.horizontalCenterOffset = 0.0; this.anchorType = Gravity.BOTTOM; allAds.put(id, this); } @@ -160,10 +162,13 @@ void show() { content.addView(adView); final float scale = activity.getResources().getDisplayMetrics().density; + int left = horizontalCenterOffset > 0 ? (int) (horizontalCenterOffset * scale) : 0; + int right = + horizontalCenterOffset < 0 ? (int) (Math.abs(horizontalCenterOffset) * scale) : 0; if (anchorType == Gravity.BOTTOM) { - content.setPadding(0, 0, 0, (int) (anchorOffset * scale)); + content.setPadding(left, 0, right, (int) (anchorOffset * scale)); } else { - content.setPadding(0, (int) (anchorOffset * scale), 0, 0); + content.setPadding(left, (int) (anchorOffset * scale), right, 0); } activity.addContentView( diff --git a/packages/firebase_admob/example/lib/main.dart b/packages/firebase_admob/example/lib/main.dart index 7daf341a8d6e..e5014d652f13 100644 --- a/packages/firebase_admob/example/lib/main.dart +++ b/packages/firebase_admob/example/lib/main.dart @@ -92,6 +92,14 @@ class _MyAppState extends State { ..load() ..show(); }), + RaisedButton( + child: const Text('SHOW BANNER WITH OFFSET'), + onPressed: () { + _bannerAd ??= createBannerAd(); + _bannerAd + ..load() + ..show(horizontalCenterOffset: -50, anchorOffset: 100); + }), RaisedButton( child: const Text('REMOVE BANNER'), onPressed: () { diff --git a/packages/firebase_admob/ios/Classes/FLTMobileAd.h b/packages/firebase_admob/ios/Classes/FLTMobileAd.h index 195164b559a1..1979be13eb4e 100644 --- a/packages/firebase_admob/ios/Classes/FLTMobileAd.h +++ b/packages/firebase_admob/ios/Classes/FLTMobileAd.h @@ -19,7 +19,9 @@ typedef enum : NSUInteger { - (FLTMobileAdStatus)status; - (void)loadWithAdUnitId:(NSString *)adUnitId targetingInfo:(NSDictionary *)targetingInfo; - (void)show; -- (void)showAtOffset:(double)anchorOffset fromAnchor:(int)anchorType; +- (void)showAtOffset:(double)anchorOffset + hCenterOffset:(double)horizontalCenterOffset + fromAnchor:(int)anchorType; - (void)dispose; @end diff --git a/packages/firebase_admob/ios/Classes/FLTMobileAd.m b/packages/firebase_admob/ios/Classes/FLTMobileAd.m index 22765d5b27c7..9e263406d620 100644 --- a/packages/firebase_admob/ios/Classes/FLTMobileAd.m +++ b/packages/firebase_admob/ios/Classes/FLTMobileAd.m @@ -14,6 +14,7 @@ @implementation FLTMobileAd FlutterMethodChannel *_channel; FLTMobileAdStatus _status; double _anchorOffset; +double _horizontalCenterOffset; int _anchorType; + (void)initialize { @@ -22,6 +23,7 @@ + (void)initialize { } _anchorType = 0; _anchorOffset = 0; + _horizontalCenterOffset = 0; if (statusToString == nil) { statusToString = @{ @@ -53,6 +55,7 @@ - (instancetype)initWithId:(NSNumber *)mobileAdId channel:(FlutterMethodChannel _channel = channel; _status = CREATED; _anchorOffset = 0; + _horizontalCenterOffset = 0; _anchorType = 0; allAds[mobileAdId] = self; } @@ -67,12 +70,15 @@ - (void)loadWithAdUnitId:(NSString *)adUnitId targetingInfo:(NSDictionary *)targ // Implemented by the Banner and Interstitial subclasses } -- (void)showAtOffset:(double)anchorOffset fromAnchor:(int)anchorType { +- (void)showAtOffset:(double)anchorOffset + hCenterOffset:(double)horizontalCenterOffset + fromAnchor:(int)anchorType { _anchorType = anchorType; _anchorOffset = anchorOffset; if (_anchorType == 0) { _anchorOffset = -_anchorOffset; } + _horizontalCenterOffset = horizontalCenterOffset; [self show]; } @@ -146,7 +152,8 @@ - (void)show { if (@available(ios 11.0, *)) { UILayoutGuide *guide = screen.safeAreaLayoutGuide; [NSLayoutConstraint activateConstraints:@[ - [_banner.centerXAnchor constraintEqualToAnchor:guide.centerXAnchor], + [_banner.centerXAnchor constraintEqualToAnchor:guide.centerXAnchor + constant:_horizontalCenterOffset], [_banner.bottomAnchor constraintEqualToAnchor:_anchorType == 0 ? guide.bottomAnchor : guide.topAnchor constant:_anchorOffset] @@ -161,7 +168,7 @@ - (void)show { - (void)placeBannerPreIos11 { UIView *screen = [FLTMobileAd rootViewController].view; - CGFloat x = screen.frame.size.width / 2 - _banner.frame.size.width / 2; + CGFloat x = screen.frame.size.width / 2 - _banner.frame.size.width / 2 + _horizontalCenterOffset; CGFloat y; if (_anchorType == 0) { y = screen.frame.size.height - _banner.frame.size.height + _anchorOffset; diff --git a/packages/firebase_admob/ios/Classes/FirebaseAdMobPlugin.m b/packages/firebase_admob/ios/Classes/FirebaseAdMobPlugin.m index 8a55c3145e51..d94762b9b61f 100644 --- a/packages/firebase_admob/ios/Classes/FirebaseAdMobPlugin.m +++ b/packages/firebase_admob/ios/Classes/FirebaseAdMobPlugin.m @@ -187,15 +187,19 @@ - (void)callShowAd:(NSNumber *)mobileAdId } double offset = 0.0; + double horizontalCenterOffset = 0.0; int type = 0; if (call.arguments[@"anchorOffset"] != nil) { offset = [call.arguments[@"anchorOffset"] doubleValue]; } + if (call.arguments[@"horizontalCenterOffset"] != nil) { + horizontalCenterOffset = [call.arguments[@"horizontalCenterOffset"] doubleValue]; + } if (call.arguments[@"anchorType"] != nil) { type = [call.arguments[@"anchorType"] isEqualToString:@"bottom"] ? 0 : 1; } - [ad showAtOffset:offset fromAnchor:type]; + [ad showAtOffset:offset hCenterOffset:horizontalCenterOffset fromAnchor:type]; result([NSNumber numberWithBool:YES]); } diff --git a/packages/firebase_admob/lib/firebase_admob.dart b/packages/firebase_admob/lib/firebase_admob.dart index de8560a00eb9..70289b2b5dc2 100644 --- a/packages/firebase_admob/lib/firebase_admob.dart +++ b/packages/firebase_admob/lib/firebase_admob.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'dart:io' show Platform; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; @@ -221,11 +222,14 @@ abstract class MobileAd { /// anchorOffset is the logical pixel offset from the edge of the screen (default 0.0) /// anchorType place advert at top or bottom of screen (default bottom) Future show( - {double anchorOffset = 0.0, AnchorType anchorType = AnchorType.bottom}) { + {double anchorOffset = 0.0, + double horizontalCenterOffset = 0.0, + AnchorType anchorType = AnchorType.bottom}) { return _invokeBooleanMethod("showAd", { 'id': id, 'anchorOffset': anchorOffset.toString(), - 'anchorType': anchorType == AnchorType.top ? "top" : "bottom" + 'horizontalCenterOffset': horizontalCenterOffset.toString(), + 'anchorType': describeEnum(anchorType) }); } diff --git a/packages/firebase_admob/pubspec.yaml b/packages/firebase_admob/pubspec.yaml index 717d5c759ed3..e6ba7fa7271a 100644 --- a/packages/firebase_admob/pubspec.yaml +++ b/packages/firebase_admob/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Firebase AdMob, supporting banner, interstitial (full-screen), and rewarded video ads author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/firebase_admob -version: 0.9.0+3 +version: 0.9.0+4 flutter: plugin: diff --git a/packages/firebase_admob/test/firebase_admob_test.dart b/packages/firebase_admob/test/firebase_admob_test.dart index 45ff0615e19c..4d85664fa614 100644 --- a/packages/firebase_admob/test/firebase_admob_test.dart +++ b/packages/firebase_admob/test/firebase_admob_test.dart @@ -73,6 +73,7 @@ void main() { isMethodCall('showAd', arguments: { 'id': id, 'anchorOffset': '0.0', + 'horizontalCenterOffset': '0.0', 'anchorType': 'bottom', }), isMethodCall('disposeAd', arguments: { @@ -92,7 +93,9 @@ void main() { expect(await interstitial.load(), true); expect( await interstitial.show( - anchorOffset: 60.0, anchorType: AnchorType.top), + anchorOffset: 60.0, + horizontalCenterOffset: 10.0, + anchorType: AnchorType.top), true); expect(await interstitial.dispose(), true); @@ -105,6 +108,7 @@ void main() { isMethodCall('showAd', arguments: { 'id': id, 'anchorOffset': '60.0', + 'horizontalCenterOffset': '10.0', 'anchorType': 'top', }), isMethodCall('disposeAd', arguments: {