How can I change this code to work without calling method - flutter

I have this code which accepts title and return a custom version of FlutterToast.
class CustomToast {
CustomToast(this.title);
final String title;
Future buildWidget() async {
return Fluttertoast.showToast(
msg: title,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black.withOpacity(0.7),
textColor: Colors.white,
fontSize: 16.0,
);
}
}
I need to call CustomToast('Toast1').buildWidget(); to make it work. How to convert the CustomToast so that I can use CustomToast.buildWidget('Toast1')?

class CustomToast {
// pass the value into buildwidget method and make the method static
static Future buildWidget(String title) async {
return Fluttertoast.showToast(
msg: title,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black.withOpacity(0.7),
textColor: Colors.white,
fontSize: 16.0,
);
}
}

Related

In flutter I am getting user input in form which I wants to save.But i am facing issue where 1 integer field can be null and user may/may not fill it

On the click of below elevated button I am calling method and sending all data collected from user.Its working fine with string values means whenever user fills or not fills the data for those string values it still saves the data but when user don't fill int field it doesn't saves it. The form should be saved even if user don't fill the int field:
Container(
//alignment: Alignment.center,
height: 35,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromARGB(255, 3, 89, 168),
),
child: ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: Colors.transparent,
// shadowColor: Colors.transparent,
// // shape: RoundedRectangleBorder(borderRadius: borderRadius),
// ),
onPressed: () {
// _formKey.currentState?.validate();
// final isValidForm = _formKey.currentState!.validate();
// if (isValidForm) {
final aptId = apID;
print('apt id add $aptId');
final int docId = dID;
print('doc id add $dID');
final int staffId = staff_Id;
print('add staff id $staffId');
final String partyName = partyNameController.text;
final String partyType = selectedValue.toString();
final String aptStatus = selectedItem.toString();
final String? paymentMode = selectedMode.toString();
//final String paymentMode = paymentModeController.text;
final String aptplace = aptplaceController.text;
final String city = cityController.text;
final String aptDate = aptDateController.text;
final String aptTime = aptTimeController.text;
final int? feesCollected =
int.parse(feesCollectedController.text).toInt();
final int totalFees =
int.parse(totalFeesController.text).toInt();
final String contactNo = contactNoController.text;
final String? comments = commentsController.text;
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => AppointmentPageFE()));
setState(() {
_futureAppointment = createAppointment(
aptId,
docId,
staffId,
partyName,
contactNo,
partyType,
aptplace,
city,
feesCollected ?? 0,
totalFees,
paymentMode ?? '',
aptDate,
aptTime,
// aptExecutive,
aptStatus,
comments ?? '',
);
});
// }
// }
},
child: const Text("Save"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Color.fromARGB(255, 3, 89, 168))),
))
The mothod where API is calling:
Future<Appointment> createAppointment(
int? aptId,
int docId,
int staffId,
//String docTitle,
// String tokenNo,
String partyName,
String contactNo,
String partyType,
String aptPlace,
String city,
int? feesCollected,
int totalFees,
String paymentMode,
String aptDate,
String aptTime,
// String aptExecutive,
String aptStatus,
String comments,
// String createdAt,
) async {
final response = await http.put(
// Uri.parse('http://192.168.0.134:8080/AtdochubJ-3/appointment/register'),
Uri.parse('http://3.108.194.111:8080/AtdochubJ-3/appointment/register'
// 'http://3.108.194.111:8080/AtdochubJ-3/appointment/register'
),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, dynamic>{
'aptId': aptId,
'docId': docId,
'staffId': staffId,
// 'docTitle': docTitle,
// 'tokenNo': tokenNo,
'partyName': partyName,
'contactNo': contactNo,
'partyType': partyType,
'aptPlace': aptPlace,
'city': city,
'feesCollected': feesCollected ?? 0,
'totalFees': totalFees,
'paymentMode': paymentMode,
'aptDate': aptDate,
'aptTime': aptTime,
//'aptExecutive': aptExecutive,
'aptStatus': aptStatus,
'comments': comments,
// 'createdAt': createdAt,
}));
if (response.statusCode == 200 || response.statusCode == 201) {
Fluttertoast.showToast(
msg: "Appointment Scheduled Successfully",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 3,
backgroundColor: Color.fromARGB(255, 77, 171, 248),
textColor: Colors.white,
fontSize: 12.0);
print("response.statusCode ${'successful'}");
return Appointment.fromJson(jsonDecode(response.body)[0]);
} else {
if (response.statusCode == 500) {
Fluttertoast.showToast(
msg: "Internal Server Error !",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 3,
backgroundColor: Color.fromARGB(255, 77, 171, 248),
textColor: Colors.white,
fontSize: 12.0);
} else {
Fluttertoast.showToast(
msg: "Failed to schedule appointment",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 3,
backgroundColor: Color.fromARGB(255, 77, 171, 248),
textColor: Colors.white,
fontSize: 12.0);
}
}
throw Exception(' Failed To Create Appointment');
}

How can I control a text typed in textField in Flutter?

signInButton(
context,
() {
if (_mail.text.isEmpty || _password.text.isEmpty) {
Fluttertoast.showToast(
msg: "Yanlış veya eksik bilgi girdiniz.",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM_RIGHT,
timeInSecForIosWeb: 3,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const StudentWidget(),
));
}
},
false,
)
I created a widget called signInButton. This widget will control the texts during login and will redirect the user to different pages accordingly. For example, if he enters the mail section as #gmail.com on the login page, he will be redirected to one page, and if he enters as #hotmail.com, he will be redirected to another page. How can I check if the user is trying to login as #hotmail or #gmail?
Container signInButton(
BuildContext context,
Function onTap,
bool isLogin,
) {
return Container(
width: 250,
height: 50,
margin: const EdgeInsets.fromLTRB(0, 30, 0, 20),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.0)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: const Color.fromARGB(255, 221, 144, 56)),
onPressed: () {
onTap();
},
child: Text('Giriş Yap',
style: GoogleFonts.poppins(
fontWeight: FontWeight.w500,
)),
),
);
}
This is my signInButton widget
TextFormField textFormField(
String text, TextEditingController controller, bool isPasswordType) {
return TextFormField(
controller: controller,
obscureText: isPasswordType,
enableSuggestions: !isPasswordType,
autocorrect: !isPasswordType,
style: GoogleFonts.montserrat(),
decoration: InputDecoration(
labelText: text,
border: const OutlineInputBorder(),
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
)),
textAlign: TextAlign.center,
validator: (value) {
if (value == "#hotmail") return 'Hata';
return null;
});
}
TextFormField Widget where I get the user's login information
Assuming that the text of the email is obtained from a textFormField or textField, you could within that widget, that is, the onChanged attribute and within the function, make the necessary checks to obtain what you are requesting. something like doing a split of the value of the mail between the '#' and the '.' that comes after the at sign to get the text that is in between this, and then see if that text obtained from the split is '==' to 'hotmail' or 'gmail'.
You can use contains to check ifa string has a specific string
signInButton(
context,
() {
if (_mail.text.isEmpty || _password.text.isEmpty) {
Fluttertoast.showToast(
msg: "Yanlış veya eksik bilgi girdiniz.",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM_RIGHT,
timeInSecForIosWeb: 3,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
} else {
if(_mail.text.contains("#gmail.com"){
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const StudentWidget(),
));
}
else{
//Navigate to another route
}
}
},
false,
)

how to check if iap transactions are finished?

i am using https://pub.dev/packages/flutter_inapp_purchase this package for in-app-purchases. i sold credit but users can receive more credit then they paid, as shown in this video :
https://youtu.be/Bo5MQdi5wGY
how can i fix this bug ? help me , please. thanks.
All relevant lines of code are in below;
code:
Future<void> initPlatformState() async {
await Purchases.setDebugLogsEnabled(true);
await Purchases.setup("RowkOdfhhydoMREZKRckltCNUNzJqgnj");
String platformVersion;
try {
platformVersion = await FlutterInappPurchase.instance.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
var result = await FlutterInappPurchase.instance.initConnection;
print('result: $result');
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
try {
String msg = await FlutterInappPurchase.instance.consumeAllItems;
print('consumeAllItems: $msg');
} catch (err) {
print('consumeAllItems error: $err');
}
_conectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// String deviceId = await PlatformDeviceId.getDeviceId;
dispose();
initPlatformState();
//FlutterInappPurchase.instance.finishTransaction(productItem);
if (productItem.productId == "oddinbetcredit10") {
print("CREDİT 10 !!!");
addCredit(deviceid, "10").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "Successfully loaded 10 credit !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit20") {
print("CREDİT 20 !!!");
addCredit(deviceid, "20").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "20 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit50") {
print("CREDİT 50 !!!");
addCredit(deviceid, "50").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "50 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit100") {
print("CREDİT 100 !!!");
addCredit(deviceid, "100").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "100 crdits successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcreditvip"){
isPremium = true;
Fluttertoast.showToast(
msg: "VIP successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
});
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
print('purchase-error: $purchaseError');
});
}
Actually, this is a bug in this plugin and it is still open on Github
The reason why you are getting more credits is because the purchaseUpdated listener receives multiple callbacks on iOS and hence your addCredit() function is called multiple times.
As a workaround, you can use the transactionId as a flag and avoid calling the code inside the purchaseUpdated listener multiple times.
Add a check
if(lastTransactionId!=productItem.transactionId)
And initialize the lastTransactionId outside the if statement body
lastTransactionId = productItem.transactionId;
Complete code:
Declare a global variable
String lastTransactionId;
And then update your listener code with this
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// String deviceId = await PlatformDeviceId.getDeviceId;
if(lastTransactionId!=productItem.transactionId){ //Added this to avoid multiple callbacks for the same transaction
dispose();
initPlatformState();
//FlutterInappPurchase.instance.finishTransaction(productItem);
if (productItem.productId == "oddinbetcredit10") {
print("CREDİT 10 !!!");
addCredit(deviceid, "10").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "Successfully loaded 10 credit !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit20") {
print("CREDİT 20 !!!");
addCredit(deviceid, "20").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "20 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit50") {
print("CREDİT 50 !!!");
addCredit(deviceid, "50").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "50 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit100") {
print("CREDİT 100 !!!");
addCredit(deviceid, "100").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "100 crdits successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcreditvip"){
isPremium = true;
Fluttertoast.showToast(
msg: "VIP successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
}
lastTransactionId = productItem.transactionId; //finally initialize your lastTransactionId with productItem.transactionId, outside the if statement
});
PS: You should call the await FlutterInappPurchase.instance.initConnection; method only once.
I hope this answer helps!

FATAL EXCEPTION: main Process: com.flutter_image, PID: 32038 kotlin.KotlinNullPointerException

I am getting this error and app crashes when I am pressing the button after compressing the image plzz help me
Thanks in advance
this is my code
onPressed: () async {
print('Selected Item = '+'$radioItemHolder');
if (radioItemHolder.contains('High')) {
print('High');
for (int i = 0;i < widget.image.length;i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(
widget.image[i].identifier);
print("path");
print(path);
File compressedFile =await FlutterNativeImage.compressImage(path, quality:
90);
images.add(compressedFile);
GallerySaver.saveImage(compressedFile.path, albumName: 'Image Resizer')
.then((bool success) {
Fluttertoast.showToast(msg: "Image saved to gallary",toastLength:
Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
}
Navigator.push(context,
MaterialPageRoute(builder: (context) => Share_Convert_Iamge(image:
images)),
);
}}
First, download this package:
https://pub.dev/packages/common_utils
Then try to force wait for the compression to complete, before running the navigation logic. Just do this:
import 'package:common_utils/common_utils.dart';
///.........
Future runImageCompressionLogic() async {
for (int i = 0;i < widget.image.length;i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(
widget.image[i].identifier);
print("path");
print(path);
await FlutterNativeImage.compressImage(path, quality:
90).then((compressedFile) {
if (!TextUtil.isEmpty(compressedFile)) {
images.add(compressedFile);
GallerySaver.saveImage(compressedFile.path,
albumName: 'Image Resizer')
.then((bool success) {
Fluttertoast.showToast(msg: "Image saved to
gallary",toastLength:
Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
});
}
}
}
}
///.....
onPressed: () async {
print('Selected Item = '+'$radioItemHolder');
if (radioItemHolder.contains('High')) {
print('High');
runImageCompressionLogic().whenComplete((){
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
Share_Convert_Iamge(image:
images)),
});
);
}}

How to get the total price of all the items in the basket?

I want to get the total price of all the items in the cart after adding items in the cart. The price should also increase when the quantity of each item is increased and also decrease when the quantity is decreased. Please help me with that,
The total variable in the cart class outputs null on the field where the total should be at.
The cart class
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dish_object.dart';
class Cart extends StatefulWidget {
final List<Dish> _cart;
Cart(this._cart);
#override
_CartState createState() => _CartState(this._cart);
}
class _CartState extends State<Cart> {
_CartState(this._cart);
List<Dish> _cart;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cart'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.send_rounded),
tooltip: "Confirm Order",
onPressed: () {
if (_cart.isNotEmpty) {
setState(() {
Fluttertoast.showToast(
msg: "Order Confirmed",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.grey,
textColor: Colors.white,
fontSize: 16.0);
});
}
if (_cart.isEmpty) {
setState(() {
Fluttertoast.showToast(
msg: "Cart Empty",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
}
}),
if (_cart.length > 0)
Padding(
padding: const EdgeInsets.only(left: 0.0),
child: CircleAvatar(
radius: 10.0,
backgroundColor: Colors.red,
foregroundColor: Colors.white,
child: Text(
_cart.length.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12.0,
),
),
),
),
],
),
body: ListView.builder(
itemCount: _cart.length,
itemBuilder: (context, index) {
var item = _cart[index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2.0),
child: Card(
elevation: 4.0,
child: ListTile(
//Leading
leading: Text(("Total: ") +
item.sum.toString() +
"\n" +
item.category +
"\n" +
"R" +
item.price.toString()),
//Title
title: Text(item.brandName +
"\n" +
"(" +
item.counter.toString() +
")"),
//Subtitle
subtitle: GestureDetector(
child: Icon(
Icons.add,
color: Colors.green,
),
onTap: () {
setState(() {
item.incrementCounter();
});
},
),
//Trailing
trailing: GestureDetector(
child: Icon(
Icons.remove_circle,
color: Colors.red,
),
onTap: () {
setState(() {
item.decrementCounter();
});
},
),
isThreeLine: true,
),
),
);
},
),
);
}
}
The dish Class
import 'package:flutter/material.dart';
class Dish {
final String category;
final String brandName;
final int price;
int counter = 1;
int count;
int sum;
int totalPrice() {
return sum = price * counter;
}
void decrementCounter() {
counter--;
}
void incrementCounter() {
counter++;
}
Dish({this.category, this.brandName, this.sum, this.price});
}
The problem is you've two variable for price inside the Dish Class,
prices and price. Where prices is always null. and price is set by the constructor. So, in the totalPrice method, you're using prices which is wrong, you should use price there instead.