refinery89_monetize_app 1.2.4 refinery89_monetize_app: ^1.2.4 copied to clipboard
The flutter plugin for the Refinery 89 Monetize App, supporting banner, outStream, interstitial (full-screen) and scrollable ads
import 'package:flutter/material.dart';
import 'package:refinery89_monetize_app/r89_sdk.dart';
void main() {
runApp(const App());
}
class App extends StatefulWidget {
const App({super.key});
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
bool _isManualInitialized = false;
bool _isAutomaticInitialized = false;
bool _isInitializationInProgress = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorObservers: [R89SDK.routeObserver],
home: Scaffold(
body: Builder(
builder: (BuildContext context) => Stack(
children: [
if (_isInitializationInProgress)
const Center(
child: Card(
child: SizedBox(width: 96, height: 96, child: CircularProgressIndicator()),
)),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (!_isManualInitialized &&
!_isAutomaticInitialized &&
!_isInitializationInProgress)
FilledButton(
onPressed: () {
// Initialize the SDK in debug mode
setState(() {
_isInitializationInProgress = true;
});
initializeInManualMode(InitializationEvents.callbacks(
onInitializationFinishedCallback: () {
setState(() {
_isManualInitialized = true;
_isInitializationInProgress = false;
});
}));
},
child: const Text('MANUAL CONFIG INITIALIZE')),
if (!_isManualInitialized &&
!_isAutomaticInitialized &&
!_isInitializationInProgress)
FilledButton(
onPressed: () {
// Initialize the SDK in debug mode
setState(() {
_isInitializationInProgress = true;
});
initializeInAutomaticMode(InitializationEvents.callbacks(
onInitializationFinishedCallback: () {
setState(() {
_isAutomaticInitialized = true;
_isInitializationInProgress = false;
});
}));
},
child: const Text('SINGLE TAG INITIALIZE')),
if (_isAutomaticInitialized)
const Flexible(child: AutomaticInitializationContent()),
if (_isManualInitialized)
const Flexible(child: ManualInitializationContent()),
],
),
),
)
],
),
),
),
);
}
}
/// Initializes the SDK in a manual mode, see [R89SDK.initialize]
void initializeInManualMode(InitializationEvents listener) async {
R89SDK.setLogLevel(LogLevel.debug);
R89SDK.setDebug();
R89SDK.initialize(
publisherId: "TestRefinery89ID",
appId: "TestDemoApp",
singleTag: false,
initializationEvents: listener);
}
class ManualInitializationContent extends StatefulWidget {
const ManualInitializationContent({super.key});
@override
State<ManualInitializationContent> createState() => _ManualInitializationContentState();
}
class _ManualInitializationContentState extends State<ManualInitializationContent> {
int _interstitialId = -1;
bool _isBannerEnabled = false;
bool _isOutstreamEnabled = false;
@override
Widget build(BuildContext context) => StreamBuilder<Object>(
stream: null,
builder: (context, snapshot) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
Align(
alignment: Alignment.topCenter,
child: ListView(
padding: EdgeInsets.only(
left: 24, right: 24, bottom: MediaQuery.of(context).size.height / 2),
children: [
const SizedBox(
height: 48,
),
FilledButton(
onPressed: () => _showAddOnAdFor(banner: true),
child: const Text('SHOW BANNER')),
FilledButton(
onPressed: () => _showAddOnAdFor(outstream: true),
child: const Text('SHOW VIDEO BANNER')),
const SizedBox(
height: 48,
),
FilledButton(
onPressed: () {
final int _infiniteScrollId = R89SDK.adFactory.createInfiniteScroll(
configurationId: ConfigBuilder.infiniteScrollTestR89ConfigId);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(
title: const Text('INFINITE SCROLL'),
),
body: _infiniteScroll(context, _infiniteScrollId),
),
));
},
child: const Text('SHOW INFINITE SCROLL')),
const SizedBox(
height: 48,
),
FilledButton(
onPressed: () async {
_interstitialId = await R89SDK.adFactory.createInterstitial(
configurationId: ConfigBuilder.interstitialTestR89ConfigId,
lifecycleCallbacks: InterstitialEventListener.callbacks(
onLoadedCallback: () =>
R89SDK.adFactory.showInterstitial(_interstitialId),
));
},
child: const Text('SHOW BANNER INTERSTITIAL AD')),
FilledButton(
onPressed: () async {
_interstitialId = await R89SDK.adFactory.createInterstitial(
configurationId: ConfigBuilder.videoInterstitialTestR89ConfigId,
lifecycleCallbacks: InterstitialEventListener.callbacks(
onLoadedCallback: () =>
R89SDK.adFactory.showInterstitial(_interstitialId),
));
},
child: const Text('SHOW VIDEO INTERSTITIAL AD')),
const SizedBox(
height: 48,
),
FilledButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.redAccent)),
onPressed: () => R89SDK.resetConsent(),
child: const Text('RESET CONSENT')),
FilledButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.redAccent)),
onPressed: () => R89SDK.reOpenConsent(),
child: const Text('RE OPEN CONSENT')),
FilledButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.redAccent)),
onPressed: () => _showAddOnAdFor(),
child: const Text('RESET ADS')),
],
),
),
if (_isOutstreamEnabled)
const R89OutStream(
configurationId: ConfigBuilder.videoOutStreamTestR89ConfigId,
),
if (_isBannerEnabled)
const R89Banner(
configurationId: ConfigBuilder.bannerTestR89ConfigId,
),
],
);
});
Widget _infiniteScroll(BuildContext context, int infiniteScrollId) => ListView.separated(
itemCount: 100,
separatorBuilder: (context, index) => const Divider(),
itemBuilder: (context, index) => Column(
children: [
ListTile(
leading: const Icon(
Icons.star_rounded,
color: Colors.amber,
),
title: Text(features[index % features.length]),
),
R89InfiniteScrollAd(infiniteScrollId: infiniteScrollId, itemIndex: index)
],
),
);
void _showAddOnAdFor({bool banner = false, bool outstream = false}) => setState(() {
_isOutstreamEnabled = outstream;
_isBannerEnabled = banner;
});
}
/// Initializes the SDK in a automatic mode, see [R89SDK.initialize],
/// After initialization SDK will use R89Tag widgets to substitute ads.
void initializeInAutomaticMode(InitializationEvents listener) async {
R89SDK.singleTagConfiguration
..initialRouteName = '/'
..addAdScreenConfig(
adScreenConfig: AdScreenConfig(screenName: '/')
// This configs a banner ad to be substituted in all places (because getAllWithTag:true)
// where R89Tag with 'banner_tag' is specified in the 'BannerTagsScreen'
..addBanner(
tag: 'banner_tag', getAllWithTag: true, wrapperRelativePositionAfter: true)
// This configs a outstream ad to be substituted for the first (because getAllWithTag:false)
// R89Tag with 'outstream_tag' is specified.
..addOutStream(
tag: 'outstream_tag', getAllWithTag: false, wrapperRelativePositionAfter: true)
// This configs a the BannerTagsScreen's close button to display an interstitial before
// handling the close action, for that the close button need to be wrapped in R89Tag
// with tag specified as 'close_button_tag'
..addInterstitial(eventToTrackButton: 'button_tag')
// This configs an interstitial ad to be displayed when navigating to BannerTagsScreen
// from the root '/' screen.
..addInterstitial(eventToTrack: 'FeaturesList'))
..addAdScreenConfig(
adScreenConfig: AdScreenConfig(screenName: 'FeaturesList')
..addInfiniteScroll(tag: 'scroll_tag')
..addInterstitial(eventToTrack: '/'),
);
R89SDK.setLogLevel(LogLevel.debug);
R89SDK.setDebug();
R89SDK.initialize(
publisherId: "TestRefinery89ID",
appId: "TestDemoApp",
singleTag: true,
initializationEvents: listener);
}
class AutomaticInitializationContent extends StatefulWidget {
const AutomaticInitializationContent({super.key});
@override
State<AutomaticInitializationContent> createState() => _AutomaticInitializationContentState();
}
class _AutomaticInitializationContentState extends State<AutomaticInitializationContent> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
const SizedBox(
height: 24,
),
R89Tag(
tag: 'banner_tag',
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Single Tag: All-in-One\nAd Management Solution for Publishers',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.grey[800],
),
),
),
),
const Divider(),
ListTile(
leading: const Icon(
Icons.arrow_circle_right_outlined,
color: Colors.amber,
),
title: const Text('INTERSTITIAL ON NAVIGATION'),
trailing: const Icon(Icons.chevron_right),
subtitle: const Text('Navigates and displays an interstitial ad.'),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const FeaturesList(),
settings: const RouteSettings(name: 'FeaturesList')));
},
),
R89Tag(
tag: 'button_tag',
child: ListTile(
leading: const Icon(
Icons.touch_app_outlined,
color: Colors.amber,
),
title: const Text('INTERSTITIAL ON TAP EVENT'),
subtitle: const Text('Displays an interstitial ad, then runs the tap action.'),
trailing: const Icon(Icons.chevron_right),
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content:
Text('This SnackBar is displayed after the interstitial get closed.')));
},
),
),
const Divider(),
const SizedBox(
height: 8,
),
const R89Tag(tag: 'banner_tag'),
R89Tag(
tag: 'outstream_tag',
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"""The Monetize App SDK has been created with a unique purpose: to make app monetization as easy and flexible as web monetization, solving the most common problems App developers and publishers' encounter""",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.grey[800],
),
),
),
),
],
),
);
}
}
class FeaturesList extends StatelessWidget {
const FeaturesList({super.key});
@override
Widget build(BuildContext context) => Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: ListView.separated(
itemCount: 100,
shrinkWrap: true,
separatorBuilder: (context, index) => const Divider(),
itemBuilder: (context, index) => R89Tag(
tag: 'scroll_tag',
itemIndex: index,
child: ListTile(
leading: const Icon(
Icons.star_rounded,
color: Colors.amber,
),
title: Text(features[index % features.length]),
),
),
),
),
ListTile(
tileColor: Colors.yellowAccent,
leading: const Icon(
Icons.arrow_back_rounded,
color: Colors.amber,
),
title: const Text('NAVIGATE BACK WITH INTERSTITIAL'),
subtitle: const Text('Navigates back and displays an interstitial ad.'),
onTap: () {
Navigator.of(context).pop();
},
),
],
),
);
}
const features = [
"All-In-One Ad Monetization",
"Performance Dashboard",
"No More App "
"Updates Required",
"Fully GDPR Compliant CMP"
];