knt_base_monetized 2.0.0 knt_base_monetized: ^2.0.0 copied to clipboard
Helper blocs for handling common in-app-purchase & admob flow
import 'package:example/ad_manager.dart';
import 'package:flutter/material.dart';
import 'package:knt_base_monetized/knt_base_monetized.dart';
import 'flavors.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Flavors.init();
MobileAds.instance.initialize();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Knt Monetized Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Knt Monetized Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
AppOpenAdBloc? _appOpenAdBloc;
InterstitialAdBloc? _interstitialAdBloc;
BannerAdBloc? _bannerAdBloc;
NativeAdBloc? _nativeAdBloc;
bool _blocLoaded = false;
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
_init();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: couldShowView
? MultiBlocProvider(
providers: [
BlocProvider(
create: (_) => _appOpenAdBloc!,
),
BlocProvider(
create: (_) => _interstitialAdBloc!,
),
BlocProvider(
create: (_) => _bannerAdBloc!,
),
BlocProvider(
create: (_) => _nativeAdBloc!,
),
],
child: const _ContentPage(),
)
: const CircularProgressIndicator(
color: Colors.orange,
),
),
);
}
void _init() async {
_blocLoaded = false;
_appOpenAdBloc = await appOpenAdBloc;
_interstitialAdBloc = await interstitialAdBloc;
_bannerAdBloc = await bannerAdBloc;
_nativeAdBloc = await nativeAdBloc;
setState(() {
_blocLoaded = true;
});
_appOpenAdBloc!.add(PrepareAdWithoutViewEvent());
_interstitialAdBloc!.add(PrepareAdWithoutViewEvent());
_bannerAdBloc!.add(PrepareAdWithViewEvent());
_nativeAdBloc!.add(PrepareAdWithViewEvent());
}
bool get couldShowView =>
_blocLoaded &&
_appOpenAdBloc != null &&
_interstitialAdBloc != null &&
_bannerAdBloc != null &&
_nativeAdBloc != null;
}
class _ContentPage extends StatelessWidget {
const _ContentPage({Key? key}) : super(key: key);
final _adTag = 'MyHomePage';
@override
Widget build(BuildContext context) {
return MultiBlocListener(
listeners: [
BlocListener<AppOpenAdBloc, BaseState>(
listener: (context, state) {
if (state is ClosedAdWithoutViewState) {
context.showInSnackBar('AppOpenAd closed!');
}
},
),
BlocListener<InterstitialAdBloc, BaseState>(
listener: (context, state) {
if (state is ClosedAdWithoutViewState) {
context.showInSnackBar('InterstitialAd closed!');
}
},
),
],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
context.read<AppOpenAdBloc>().add(ShowAdWithoutViewEvent(_adTag));
},
child: const Text('Show App Open Ads'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
context
.read<InterstitialAdBloc>()
.add(ShowAdWithoutViewEvent(_adTag));
},
child: const Text('Show Interstitial Ads'),
),
const SizedBox(height: 16),
BlocBuilder<BannerAdBloc, BaseState>(
builder: (context, state) =>
(state is LoadedAdWithViewState && state.ad != null)
? Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
height: 50,
child: AdWidget(ad: state.ad!),
)
: const SizedBox(),
),
const SizedBox(height: 16),
BlocBuilder<NativeAdBloc, BaseState>(
builder: (context, state) =>
(state is LoadedAdWithViewState && state.ad != null)
? Container(
width: MediaQuery.of(context).size.width,
height: 360,
padding: const EdgeInsets.symmetric(horizontal: 4),
color: Colors.white,
alignment: Alignment.center,
child: AdWidget(ad: state.ad!),
)
: const SizedBox(),
),
],
),
);
}
}
extension on BuildContext {
void showInSnackBar(String message) {
ScaffoldMessenger.of(this).removeCurrentSnackBar();
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
duration: const Duration(milliseconds: 3000),
content: Text(message),
));
}
}