Last active
June 15, 2020 05:12
-
-
Save axilaris/2b186c7a4073671128e8cacc09dfc384 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PurchaseDialog extends StatefulWidget with NavigationStates { | |
@override | |
_PurchaseDialogState createState() => _PurchaseDialogState(); | |
PurchaseDialog(); | |
} | |
class _PurchaseDialogState extends State<PurchaseDialog> { | |
_PurchaseDialogState(); | |
String title = "Pro Version"; | |
String description = "Full App Access"; | |
String purchaseButtonText = "Loading..."; | |
bool isLoading = true; | |
// inapp | |
StreamSubscription _purchaseUpdatedSubscription; | |
StreamSubscription _purchaseErrorSubscription; | |
StreamSubscription _conectionSubscription; | |
final List<String> _productLists = Platform.isAndroid | |
? [ | |
// 'android.test.purchased', | |
// 'android.test.canceled', | |
'example_pro_inapp_android', | |
] | |
: ['example_pro_inapp']; | |
// | |
String _platformVersion = 'Unknown'; | |
List<IAPItem> _items = []; | |
List<PurchasedItem> _purchases = []; | |
static const double padding = 20.0; | |
final primaryColor = const Color(0xFF75A2EA); | |
final grayColor = const Color(0xFF939393); | |
void _requestPurchase(IAPItem item) { | |
FlutterInappPurchase.instance.requestPurchase(item.productId); | |
} | |
Future _getProduct() async { | |
print("_getProduct"); | |
List<IAPItem> items; | |
try { | |
items = await FlutterInappPurchase.instance.getProducts(_productLists); | |
print('flutterInappPurchase.instance.getProducts'); | |
} catch (err) { | |
print('flutterInappPurchase.instance.getProducts error: $err'); | |
Navigator.of(context).pop(); | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
// return object of type Dialog | |
return AlertDialog( | |
title: new Text("Failure", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 33, | |
fontWeight: FontWeight.w800, | |
color: Color(0xFFF44336 ), | |
),), | |
content: new Text("Error. Possibly no internet. Please turn on your internet.", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
actions: <Widget>[ | |
// usually buttons at the bottom of the dialog | |
new FlatButton( | |
child: new Text("Close", | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
onPressed: () { | |
Navigator.of(context).pop(); | |
}, | |
), | |
], | |
); | |
}, | |
); | |
return; | |
} | |
for (var item in items) { | |
print('${item.toString()}'); | |
this._items.add(item); | |
} | |
print("items.length"); | |
print(items.length); | |
if (items.length > 0) | |
{ | |
if (items[items.length-1].title == "") | |
{ | |
print("empty title"); | |
} | |
title = items[items.length-1].title; | |
description = items[items.length-1].description + "\n" + items[items.length-1].localizedPrice; | |
purchaseButtonText = "Purchase"; | |
isLoading = false; | |
} | |
setState(() { | |
this._items = items; | |
this._purchases = []; | |
}); | |
} | |
Future _getPurchases() async { | |
List<PurchasedItem> items = | |
await FlutterInappPurchase.instance.getAvailablePurchases(); | |
for (var item in items) { | |
print('${item.toString()}'); | |
this._purchases.add(item); | |
} | |
setState(() { | |
this._items = []; | |
this._purchases = items; | |
}); | |
} | |
Future _getPurchaseHistory() async { | |
print("_getPurchaseHistory"); | |
List<PurchasedItem> items = await FlutterInappPurchase.instance.getPurchaseHistory(); | |
print(items.length); | |
for (var item in items) { | |
print('${item.toString()}'); | |
this._purchases.add(item); | |
} | |
setState(() { | |
this._items = []; | |
this._purchases = items; | |
}); | |
} | |
// Platform messages are asynchronous, so we initialize in an async method. | |
Future<void> initInAppPlatformState() async { | |
String platformVersion; | |
// Platform messages may fail, so we use a try/catch PlatformException. | |
try { | |
platformVersion = await FlutterInappPurchase.instance.platformVersion; | |
} on PlatformException { | |
platformVersion = 'Failed to get platform version.'; | |
} | |
// prepare | |
var result = await FlutterInappPurchase.instance.initConnection; | |
print('result: $result'); | |
// If the widget was removed from the tree while the asynchronous platform | |
// message was in flight, we want to discard the reply rather than calling | |
// setState to update our non-existent appearance. | |
if (!mounted) return; | |
setState(() { | |
_platformVersion = platformVersion; | |
}); | |
// refresh items for android | |
try { | |
String msg = await FlutterInappPurchase.instance.consumeAllItems; | |
print('consumeAllItems: $msg'); | |
} catch (err) { | |
print('consumeAllItems error: $err'); | |
} | |
_purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) async { | |
print('purchase-updated: $productItem'); | |
bool result = await savePurchaseStatusPreference(true); | |
print(isPurchasedObject.isPurchased); | |
Navigator.of(context).pop(); | |
}); | |
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) { | |
print('purchase-error: $purchaseError'); | |
Navigator.of(context).pop(); | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
// return object of type Dialog | |
return AlertDialog( | |
title: new Text("Failure", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 33, | |
fontWeight: FontWeight.w800, | |
color: Color(0xFFF44336 ), | |
),), | |
content: new Text("Error Purchase", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
actions: <Widget>[ | |
// usually buttons at the bottom of the dialog | |
new FlatButton( | |
child: new Text("Close", | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
onPressed: () { | |
Navigator.of(context).pop(); | |
}, | |
), | |
], | |
); | |
}, | |
); | |
}); | |
_getProduct(); | |
} | |
@override | |
void initState(){ | |
super.initState(); | |
initInAppPlatformState(); | |
} | |
@override | |
void dispose(){ | |
super.dispose(); | |
} | |
void purchaseOnPressedAction() async | |
{ | |
print("purchaseOnPressedAction"); | |
if (_items.length > 0) | |
{ | |
print(_items[_items.length-1].productId); | |
_requestPurchase(_items[_items.length-1]); | |
} | |
else | |
{ | |
print("error nothing to purchase"); | |
Navigator.pop(context); | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
// return object of type Dialog | |
return AlertDialog( | |
title: new Text("Failure", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 33, | |
fontWeight: FontWeight.w800, | |
color: Color(0xFFF44336 ), | |
),), | |
content: new Text("Error - Nothing To Purchase", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
actions: <Widget>[ | |
// usually buttons at the bottom of the dialog | |
new FlatButton( | |
child: new Text("Close", | |
style: TextStyle( | |
fontSize: 20, | |
fontWeight: FontWeight.w400, | |
),), | |
onPressed: () { | |
Navigator.of(context).pop(); | |
}, | |
), | |
], | |
); | |
}, | |
); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Dialog( | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(padding), | |
), | |
child: Stack( | |
children: <Widget>[ | |
Container( | |
padding: EdgeInsets.all(padding), | |
decoration: BoxDecoration( | |
color: Colors.white, | |
shape: BoxShape.rectangle, | |
borderRadius: BorderRadius.circular(padding), | |
boxShadow: [ | |
BoxShadow( | |
color: Colors.black, | |
blurRadius: 10.0, | |
offset: const Offset(0.0, 10.0), | |
), | |
]), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
SizedBox(height: 24.0), | |
AutoSizeText( | |
title, | |
maxLines: 2, | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
color: primaryColor, | |
fontSize: 25.0, | |
), | |
), | |
SizedBox(height: 24.0), | |
AutoSizeText( | |
description, | |
maxLines: 4, | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
color: grayColor, | |
fontSize: 18.0, | |
), | |
), | |
SizedBox(height: 24.0), | |
RaisedButton( | |
color: primaryColor, | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(30.0)), | |
child: Padding( | |
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10), | |
child: AutoSizeText( | |
purchaseButtonText, | |
maxLines: 1, | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.w400, | |
color: Colors.white, | |
), | |
), | |
), | |
onPressed: (isLoading) ? null : () => purchaseOnPressedAction(), | |
), | |
SizedBox(height: 10.0), | |
showSecondaryButton(context), | |
], | |
), | |
) | |
], | |
), | |
); | |
} | |
showSecondaryButton(BuildContext context) { | |
return FlatButton( | |
child: AutoSizeText( | |
"Cancel", | |
maxLines: 1, | |
style: TextStyle( | |
fontSize: 18, | |
color: primaryColor, | |
fontWeight: FontWeight.w400, | |
), | |
), | |
onPressed: () { | |
print("secondary button pressed"); | |
Navigator.of(context).pop(); | |
}, | |
); | |
} | |
} |
PurchaseDialog above is called in this way:
showDialog(
context: context,
builder: (BuildContext context) => PurchaseDialog(),
).then((value) {
setState(() {
});
});
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
notice in the last part:
showSecondaryButton(BuildContext context) {
....
Navigator.of(context).pop(); <--- this will cause the error below. infact, any pop in the code will cause the same error
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'findAncestorStateOfType' was called on null.