Radio Button while using in List builder - flutter

I faced problem of separating value of radio button . As I use multiple radio buttons in multiple list that i get from APi. so every time , when i select one radio button ,it selects all radio button of this type in all list. for example: radio 1 = check , radio 2 = unchecked in list 1 and list 2. i select radio 1 of list 1 but both radio 1 of list 1 and list 2 selected.
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:http/http.dart' as http;
import 'package:progress_dialog/progress_dialog.dart';
import 'package:project40/Constants/APIConstants.dart';
import 'package:project40/Constants/styleConstant.dart';
import 'package:project40/screens/home_screen.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:project40/api/add_filter_api.dart';
import 'package:project40/provider/add_post_provider.dart';
import 'package:provider/provider.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:project40/Constants/globals.dart' as globals;
class FilterScreen extends StatefulWidget {
#override
_FilterScreenState createState() => _FilterScreenState();
}
class _FilterScreenState extends State<FilterScreen> {
var jsonData;
//String filterVariable;
int school_everyone = 0;
bool all_Feed = true;
AddPostProvider _addPostProvider;
int length = 0;
int v = 0;
Future mySchools() async {
print("test");
//loading dialog appears
ProgressDialog pr;
pr = new ProgressDialog(context, showLogs: true);
pr.style(
progressWidget: Container(
width: 50,
child: Lottie.asset("assets/json/360-loader.json"),
),
message: 'Please wait...');
pr.show();
//api link
String url = baseURL + mySchoolURL;
//getting user token
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("token");
print(token);
//create post request
http.Response response = await http.get(url, headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer $token',
}).catchError((e) => print(e));
print('successs');
pr.hide();
if (response == null) {
//appear dialog if any error will be occured
Alert(
context: context,
title: "",
type: AlertType.none,
desc: "Something went wrong. Please try again",
buttons: [
DialogButton(
child: Text(
"OK",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
pr.hide();
},
width: 120,
)
],
).show();
} else {
jsonData = jsonDecode(response.body);
if (jsonData["status_code"] == 200) {
print(jsonData);
// if (all_Feed == true) {
// filterVariable = "All School";
// }
// print(filterVariable);
pr.hide();
//store the no of institutions
length = jsonData["data"].length;
setState(() {});
} else {
pr.hide();
//if error occured
Alert(
context: context,
type: AlertType.none,
title: "",
desc: jsonData["message"],
buttons: [
DialogButton(
child: Text(
"OK",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
pr.hide();
},
width: 120,
)
],
).show();
}
}
return jsonDecode(response.body);
}
#override
void initState() {
super.initState();
mySchools();
if (all_Feed == true) {
school_everyone = 0;
}
if (school_everyone == 1) {
all_Feed = false;
}
// if (all_Feed == false) {
// setState(() {
// selectedRadio(2);
// });
// }
// if (school_everyone == 1) {
// setState(() {
// all_school = 0;
// });
// }
}
void selectedRadio(int value) {
setState(() {
all_Feed = false;
school_everyone = value;
});
}
#override
Widget build(BuildContext context) {
_addPostProvider = Provider.of<AddPostProvider>(context, listen: false);
return Material(
child: Scaffold(
backgroundColor: Colors.grey,
body: Stack(
//alignment: AlignmentDirectional.topCenter,
children: [
Container(
padding: EdgeInsets.only(top: 5),
decoration: BoxDecoration(
//borderRadius: BorderRadius.circular(50),
),
child: Padding(
padding: const EdgeInsets.only(top: 45),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
color: Colors.white,
),
child: Column(
children: [
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.arrow_back),
),
onTap: () {
Navigator.pop(context);
},
),
Text(
"Feed Filter",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "Roboto",
fontSize: 20,
fontWeight: FontWeight.bold),
),
Container(width: 32.0),
],
),
Divider(
thickness: 1,
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: GestureDetector(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomeScreen()));
},
child: allFilter(
Checkbox(
value: all_Feed,
activeColor: Colors.black,
onChanged: (value) {
setState(() {
all_Feed = value;
if (all_Feed == true) {
school_everyone = 0;
} else {
school_everyone = 1;
}
});
}),
Text(
"All school",
style: DayMoodRobotoStyle.heading5c,
)),
),
),
Expanded(
child: ListView.builder(
itemCount: length,
itemBuilder: (context, index) {
return SingleChildScrollView(
child: Container(
child: schoolUseage(
jsonData["data"][index]["institution"]
["name"] ??
"",
jsonData["data"][index]["institution"]
["none"] ??
"",
jsonData["data"][index]["institution"]
["_id"] ??
"",
jsonData["data"][index]["year"]["year"] ??
"",
jsonData["data"][index]["year"]["_id"] ??
"",
jsonData["data"][index]["program"] == null
? ""
: jsonData["data"][index]["program"]
["title"],
jsonData["data"][index]["program"] == null
? ""
: jsonData["data"][index]["program"]
["_id"],
index),
),
);
}),
),
InkWell(
onTap: () async {
// var response =
// await GetFilterPostAPI().getFilterPostApi(
// ids: globals.filterVariable,
// );
// print('add filter response$response');
// if (response['status_code'] == 200) {
// _addPostProvider.addPostProgress = false;
Navigator.pop(context);
Fluttertoast.showToast(
msg: 'Filter Add Successfully..');
// _addPostProvider.addPostProgress = false;
// } else {
// Fluttertoast.showToast(msg: response['message']);
// _addPostProvider.addPostProgress = false;
// }
},
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Container(
alignment: Alignment.center,
width: double.infinity,
height: 55.0,
margin: EdgeInsets.symmetric(
horizontal: 20,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(28.0),
color: const Color(0xff0188ba),
boxShadow: [
BoxShadow(
color: const Color(0x333F51B5).withOpacity(0.2),
offset: Offset(0, 20),
blurRadius: 20,
),
],
),
child: Text(
'Filter',
style: DayMoodRobotoStyle.heading5,
textAlign: TextAlign.center,
),
),
),
SizedBox(
height: 20,
),
],
),
),
),
),
],
),
),
);
}
Widget schoolInfo(Radio icon, Expanded schoolname) {
return Row(
children: [icon, schoolname],
);
}
Widget allFilter(Checkbox icon, Text schoolname) {
return Row(
children: [icon, schoolname],
);
}
Widget schoolUseage(
String schooolName,
String school_id,
String _id,
String classOf,
String classof_id,
String department,
String department_id,
int index) {
String s1 = index.toString();
String s2 = school_everyone.toString();
String s = s1 + s2;
v = int.parse(s);
return Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
schooolName,
style: TextStyle(
color: all_Feed == true ? Colors.grey : Colors.blue,
fontSize: 17,
fontFamily: "Ubuntu",
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
),
),
),
SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: all_Feed == true
? IgnorePointer(
ignoring: true,
child: schoolInfo(
Radio(
activeColor: Colors.black,
value: null,
groupValue: index,
onChanged: (value) {
selectedRadio(value);
globals.filterVariable =
"all_" + school_id + "program_" + _id;
}),
Expanded(
child: Text(
"Everyone",
style: TextStyle(
fontFamily: 'Ubuntu',
fontSize: 15,
color: Colors.grey,
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
),
)),
)
: schoolInfo(
Radio(
activeColor: Colors.black,
value: 1,
groupValue: v,
onChanged: (value) {
setState(() {
// String s1 = index.toString();
// String s2 = value.toString();
// String s = s1 + s2;
// v = int.parse(s);
selectedRadio(value);
globals.filterVariable = "all_$_id";
});
}),
Expanded(
child: Text(
"Everyone",
style: DayMoodRobotoStyle.heading5c,
),
)),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: all_Feed == true
? IgnorePointer(
child: schoolInfo(
Radio(
activeColor: Colors.black,
value: 2,
groupValue: school_everyone,
onChanged: (value) {
selectedRadio(value);
}),
Expanded(
child: Text(
"None",
style: TextStyle(
fontFamily: 'Ubuntu',
fontSize: 15,
color: Colors.grey,
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
),
)),
)
: schoolInfo(
Radio(
activeColor: Colors.black,
value: 2,
groupValue: v,
onChanged: (value) {
setState(() {
// String s1 = index.toString();
// String s2 = value.toString();
// String s = s1 + s2;
// v = int.parse(s);
selectedRadio(value);
globals.filterVariable = "none_" + _id;
});
}),
Expanded(
child: Text(
"None",
style: DayMoodRobotoStyle.heading5c,
),
)),
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: all_Feed == true
? IgnorePointer(
child: schoolInfo(
Radio(
activeColor: Colors.black,
value: 2,
groupValue: school_everyone,
onChanged: (value) {
selectedRadio(value);
}),
Expanded(
child: Text(
department + " Only",
style: TextStyle(
fontFamily: 'Ubuntu',
fontSize: 15,
color: Colors.grey,
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
maxLines: 2,
),
),
),
)
: schoolInfo(
Radio(
activeColor: Colors.black,
value: 3,
groupValue: v,
onChanged: (value) {
setState(() {
// String s1 = index.toString();
// String s2 = value.toString();
// String s = s2 + s1;
// v = int.parse(s);
selectedRadio(value);
globals.filterVariable = "program_" + _id;
});
}),
Expanded(
child: Text(
department + " Only",
style: DayMoodRobotoStyle.heading5c,
maxLines: 2,
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: all_Feed == true
? IgnorePointer(
child: schoolInfo(
Radio(
activeColor: Colors.black,
value: classof_id,
groupValue: school_id,
onChanged: (value) {
selectedRadio(value);
}),
Expanded(
child: Text(
"Class of " + classOf + " Only",
style: TextStyle(
fontFamily: 'Ubuntu',
fontSize: 15,
color: Colors.grey,
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
),
)),
)
: schoolInfo(
Radio(
activeColor: Colors.black,
value: 4,
groupValue: v,
onChanged: (value) {
setState(() {
// String s1 = index.toString();
// String s2 = value.toString();
// String s = s2 + s1;
// v = int.parse(s);
selectedRadio(value);
globals.filterVariable = "year_" + _id;
//classOf + "_" + school_id;
});
}),
Expanded(
child: Text(
"Class of " + classOf + " Only",
style: DayMoodRobotoStyle.heading5c,
),
)),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: all_Feed == true
? IgnorePointer(
child: schoolInfo(
Radio(
activeColor: Colors.black,
value: all_Feed == true ? 0 : department_id,
groupValue: school_id,
onChanged: (value) {
selectedRadio(value);
}),
Expanded(
child: Text(
department + " - " + classOf,
style: TextStyle(
fontFamily: 'Ubuntu',
fontSize: 15,
color: Colors.grey,
letterSpacing: 0.17,
fontWeight: FontWeight.w700),
),
)),
)
: schoolInfo(
Radio(
activeColor: Colors.black,
value: 5,
groupValue: v,
onChanged: (value) {
setState(() {
// String s1 = index.toString();
// String s2 = value.toString();
// String s = s2 + s1;
// v = int.parse(s);
selectedRadio(value);
globals.filterVariable = "programyear_" + _id;
// department + classOf + "_" + school_id;
});
}),
Expanded(
child: Text(
department + " - " + classOf,
style: DayMoodRobotoStyle.heading5c,
),
)),
),
SizedBox(
height: 20,
),
],
);
}
}

Here is the minimum implementation of 2Radio button groups.
class _TestState extends State<Test> {
int group1Value;
int group2Value;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Radio"),
),
body: Column(
children: [
//Let suppose this is group 1
Row(
children: [
Radio(
value: 0,
groupValue: group1Value,
onChanged: (value) {
setState(() {
group1Value = value;
});
},
),
Expanded(child: Text("Radio1")),
],
),
Row(
children: [
Radio(
value: 1,
groupValue: group1Value,
onChanged: (value) {
setState(() {
group1Value = value;
});
},
),
Expanded(child: Text("Radio2")),
],
),
Row(
children: [
Radio(
value: 2,
groupValue: group1Value,
onChanged: (value) {
setState(() {
group1Value = value;
});
},
),
Expanded(child: Text("Radio3")),
],
),
SizedBox(height: 20),
Text(
"Second Group",
style: Theme.of(context).textTheme.subtitle1.copyWith(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
//suppose this is group 2
Row(
children: [
Radio(
value: 0,
groupValue: group2Value,
onChanged: (value) {
setState(() {
group2Value = value;
});
},
),
Expanded(child: Text("Radio1")),
],
),
Row(
children: [
Radio(
value: 1,
groupValue: group2Value,
onChanged: (value) {
setState(() {
group2Value = value;
});
},
),
Expanded(child: Text("Radio2")),
],
),
Row(
children: [
Radio(
value: 2,
groupValue: group2Value,
onChanged: (value) {
setState(() {
group2Value = value;
});
},
),
Expanded(child: Text("Radio3")),
],
),
],
),
);
}
}
Here are the results

Related

The state of my checkboxes keep returning to their original value in flutter

I have a profile page with some widgets which after saving and redrawing, they keep their new states, but my checkboxes do not, and I have not modified them at all. The new value is being saved on the database, but on the UI it's not preserved. If I turn the email checkbox to true, the 'true' boolean is saved, but it's not displayed on the frontend after pressing the submit button.
class _ProfilePageState extends State<ProfilePage> {
final _formKey = GlobalKey<FormState>();
bool? emailIsChecked = false;
bool? smsisChecked = false;
bool isTextFieldEnabled = false;
bool isIgnored = true;
bool isVisible = false;
bool editIsVisible = true;
bool emailIsEnabled = false;
bool smsIsEnabled = false;
bool nameEdit = false;
late TextEditingController countryController;
late TextEditingController languageController;
#override
void initState() {
super.initState();
countryController = TextEditingController(text: globals.signedInUser!.country);
languageController = TextEditingController(text: globals.signedInUser!.language);
selectedCountry = globals.signedInUser!.country;
selectedLanguage = globals.signedInUser!.language;
globals.signedInUser!.notifications.forEach(
(element) {
if ((element['type']) == 'Email') {
emailIsChecked = element['status'];
}
if ((element['type']) == 'SMS') {
smsisChecked = element['status'];
}
},
);
cleanInputStates();
}
#override
void dispose() {
countryController.dispose();
languageController.dispose();
super.dispose();
}
checkEditVisibility() {
if (editIsVisible == true) {
return true;
}
if (editIsVisible == false) {
return false;
}
}
checkEditAvailability() {
if (editIsVisible == false) {
return true;
}
if (editIsVisible == true) {
return false;
}
}
cleanInputStates() {
isTextFieldEnabled = false;
isIgnored = true;
editIsVisible = true;
isVisible = false;
smsIsEnabled = false;
emailIsEnabled = false;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
key: _formKey,
child: Row(
children: [
Flexible(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Visibility(
visible: editIsVisible,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
child: ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green)),
icon: const Icon(Icons.edit),
label: Text('Edit'),
onPressed: () {
setState(() {
isTextFieldEnabled = true;
isIgnored = false;
isVisible = true;
editIsVisible = false;
smsIsEnabled = true;
emailIsEnabled = true;
});
}),
),
SizedBox(
width: 250,
)
],
),
SizedBox(
height: 30,
),
Flexible(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 20,
),
... // TextFieldInputs
Row(
children: [
Container(
child: Text(
"Country: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
),
SizedBox(
width: 100,
),
Container(
width: 300,
child: IgnorePointer(
ignoring: isIgnored,
child: DropdownButtonFormField2(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
isExpanded: true,
hint: const Text(
'Select Your Country',
style: TextStyle(fontSize: 14),
),
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.black45,
),
iconSize: 30,
buttonHeight: 60,
buttonPadding: const EdgeInsets.only(left: 20, right: 10),
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
items: countryItems
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
validator: (valueCountry) {
if (valueCountry == null) {
return 'Please select country.';
}
return null;
},
value: selectedCountry,
onChanged: (String? valueCountry) {
selectedCountry = valueCountry;
setState(() {
valueCountry;
});
},
),
),
),
// ),
],
),
SizedBox(
height: 20,
),
Row(
children: [
Container(
child: Text(
"Language: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
),
SizedBox(
width: 80,
),
Container(
width: 300,
child: IgnorePointer(
ignoring: isIgnored,
child: DropdownButtonFormField2(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
isExpanded: true,
hint: const Text(
'Select Your Language',
style: TextStyle(fontSize: 14),
),
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.black45,
),
iconSize: 30,
buttonHeight: 60,
buttonPadding: const EdgeInsets.only(left: 20, right: 10),
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
items: languageItems
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
value: selectedLanguage,
validator: (valueLanguage) {
if (valueLanguage == null) {
return 'Please select language.';
}
return null;
},
onChanged: (String? valueLanguage) {
selectedLanguage = valueLanguage;
setState(() {
valueLanguage;
});
},
),
),
),
// ),
],
),
Row()
],
),
SizedBox(
width: 120,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
child: Row(
children: [
Text(
"Receive notifications by: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
],
),
),
],
),
SizedBox(
height: 10,
),
Row(
children: [
Container(
width: 300,
child: CheckboxListTile(
enabled: emailIsEnabled,
title: Text("E-mail"),
value: emailIsChecked,
onChanged: (bool? newEmailValue) {
setState(() {
emailIsChecked = newEmailValue;
});
},
activeColor: Colors.green,
),
),
],
),
Row(
children: [
Container(
width: 300,
child: CheckboxListTile(
enabled: smsIsEnabled,
title: Text("SMS"),
value: smsisChecked,
onChanged: (bool? newSmsValue) {
setState(() {
smsisChecked = newSmsValue;
});
},
activeColor: Colors.green,
),
),
],
),
SizedBox(
height: 100,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Visibility(
visible: isVisible,
child: Row(
children: <Widget>[
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.red)),
onPressed: () {
setState(() {
cleanInputStates();
_formKey.currentState!.reset();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage()));
});
print("Cleaning states");
},
child: Text("Dismiss"),
),
SizedBox(
width: 100,
),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.green)),
onPressed: () {
if (_formKey.currentState!.validate()) {
final userInfo = {
"_id": globals.signedInUser!.userId,
"firstName": firstnameTextController.text,
"lastName": lastnameTextController.text,
"email": emailTextController.text,
"phoneNumber": phoneNumberTextController.text,
"country": selectedCountry.toString(),
"language": selectedLanguage.toString(),
"notifications": [
{"type": "Email", "status": emailIsChecked},
{"type": "SMS", "status": smsisChecked}
]
};
globals.socketController.updateUser(userInfo);
Fluttertoast.showToast(
msg: "Applying changes.", // message
toastLength: Toast.LENGTH_LONG, // length
gravity: ToastGravity.BOTTOM_RIGHT, // location
timeInSecForIosWeb: 2,
webBgColor: "#4caf50",
);
}
print("DATA IS BEING SAVED");
setState(() {
if (_formKey.currentState!.validate()) {
globals.signedInUser!.email =
emailTextController.text;
globals.signedInUser!.phoneNumber =
phoneNumberTextController.text;
globals.signedInUser!.firstName =
firstnameTextController.text;
globals.signedInUser!.lastName =
lastnameTextController.text;
globals.signedInUser!.country =
selectedCountry as String;
globals.signedInUser!.language =
selectedLanguage as String;
cleanInputStates();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage()));
} else {
print("ingresando else");
}
});
},
child: Text("Save"),
),
],
),
)
],
)
],
),
],
),
),
),
],
), //Column ends here
),
),
],
),
),
);
}
}
Update: After some testings and workarounds, I found that the second issue was due to not assigning a new value prior to returning to the initState. To do that, I added the following code segment into the setState() of the submit button, which is the fetch of the notification parameters within the initState() but assigning the new checkbox values into the array. Additionally, I removed the cleanInputStates(); on the initState as #Paulo mentioned and everything else kept the same.
globals.signedInUser!.notifications.forEach(
(element) {
if ((element['type']) == 'Email') {
element['status'] = emailIsChecked;
}
if ((element['type']) == 'SMS') {
element['status'] = smsisChecked;
}
},
);

Product list is not Showing in this flutter screen

My product has been added to Firebase, but there is a problem with the dashboard's list not appearing. No errors are displayed on the console or the screen.I'm not sure where the problem is appearing in the code or firebase. I'm basically developing an e-commerce app that users should use to sell their goods.
class _SellerDashBoardState extends State<SellerDashBoard> {
MaterialColor active = Colors.red;
MaterialColor notActive = Colors.grey;
List<SellerProductItem> products = [
const SellerProductItem(),
];
#override
Widget build(BuildContext context) {
print(parentIdGlobal);
print(FirebaseAuth.instance.currentUser!.uid);
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text(
'Seller Dashboard',
style: TextStyle(
fontSize: ResponsiveWidget.isSmallScreen(context) ? 17.0 : 25.0),
),
actions: [
IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 27.0,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => AddProductForm(),
),
);
},
),
IconButton(
icon: WebsafeSvg.asset(
'assets/images/sold-out.svg',
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => SoldItemScreens(),
),
);
},
),
],
),
body: Column(
children: <Widget>[
const SizedBox(
height: 10.0,
),
Container(
color: const Color(0xffF7F7F7),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("items")
.where('seller', isEqualTo: parentIdGlobal)
.where('isSold', isEqualTo: true)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final List<QueryDocumentSnapshot<Map<String, dynamic>>>
docSnapList = snapshot.data?.docs ?? [];
if (docSnapList.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: WebsafeSvg.asset(
'assets/images/empty_dashboard.svg',
fit: BoxFit.cover,
height: MediaQuery.of(context).size.height / 5,
),
),
);
}
final List<Map<String, dynamic>> docList = docSnapList
.map((QueryDocumentSnapshot<Map<String, dynamic>>
queryDocumentSnapshot) =>
queryDocumentSnapshot.data())
.toList();
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: docList.length,
itemBuilder: (context, index) {
bool isSold = docList[index]['isSold'] ?? true;
bool isLiked = docList[index]['isLiked'] ?? true;
String itemId = docList[index]['itemId'] ?? '';
String seller = docList[index]['seller'] ?? '';
String sellerName = docList[index]['sellerName'] ?? '';
String title = docList[index]['title'] ?? '';
String desc = docList[index]['desc'] ?? '';
String price = docList[index]['price'] ?? '';
String condition = docList[index]['condition'] ?? '';
String category = docList[index]['category'] ?? '';
String location = docList[index]['location'] ?? '';
String itemImage =
docList[index]['imageDownloadUrl'] ?? '';
return SellerProductItem(
itemId: itemId,
seller: seller,
sellerName: sellerName,
title: title,
desc: desc,
price: price,
itemImage: itemImage,
isLiked: isLiked,
isSold: isSold,
category: category,
condition: condition,
location: location,
);
},
);
},
add product screen
class _AddProductFormState extends State<AddProductForm> {
TextEditingController controllerTitle = TextEditingController();
TextEditingController controllerPrice = TextEditingController();
TextEditingController controllerDescription = TextEditingController();
TextEditingController controllerlocation = TextEditingController();
GlobalKey<FormState> _formKey = GlobalKey();
String selectedCondition = 'New';
String selectedCategory = 'Cosmetic Aids';
bool isReadOnly = true;
File? pickedImage;
bool imgStatus = false;
List<String> conditionList = [
'New',
'Like New',
'Good',
'Fair',
'Poor',
];
List<String> categoryList = [
'Cosmetic Aids',
'Mobility Products',
'Bath Safety Products',
'Others',
];
bool _switchValue = false;
Future<void> addGroceryItemToToDb() async {
final itemId = Uuid().v4();
String? url;
if (pickedImage != null) {
print(parentIdGlobal);
print(FirebaseAuth.instance.currentUser!.uid);
Reference storage = FirebaseStorage.instance
.ref()
.child('users/${FirebaseAuth.instance.currentUser!.uid}/$itemId/item_pic');
UploadTask uploadTask = storage.putFile(pickedImage!);
final temp = await (await uploadTask).ref.getDownloadURL();
url = temp.toString();
}
FirebaseFirestore.instance.collection('items').doc(itemId).set(
{
'itemId': itemId,
'timestamp': DateTime.now(),
'seller': parentIdGlobal,
'sellerName': userNameGlobal,
'title': controllerTitle.text,
'price': controllerPrice.text,
'desc': controllerDescription.text,
'condition': selectedCondition,
'category': selectedCategory,
'location': controllerlocation.text,
'isSold': false,
'imageDownloadUrl': url,
},
);
} // adds grocery item to db
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 1.0,
centerTitle: true,
title: Text(
'Add a Product',
),
),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
_selectImageButton(context),
_writeTitle(),
_writePrice(),
_giveitfree(),
_conditionDropDown(),
_writeDescription(),
_categoryDropDown(),
_writeLocation(),
Align(
alignment: Alignment.bottomCenter,
child: _addProductButton(context)),
],
),
),
),
);
}
_selectImageButton(BuildContext context) {
return GestureDetector(
onTap: () async {
await Permission.photos.request();
var status = await Permission.photos.status;
if (status.isGranted) {
try {
XFile? _pickedImage = await ImagePicker().pickImage(
source: ImageSource.gallery,
maxWidth: 100,
maxHeight: 100,
imageQuality: 100
) ;
if(_pickedImage !=null){
pickedImage = File(_pickedImage.path);
setState(() {
imgStatus = true;
});
} }catch (e) {
print(e.toString());
}
} else if (status.isDenied || status.isRestricted) {
print('Permission Denied');
showDialog(
context: context,
builder: (context) {
if (Platform.isAndroid)
return AlertDialog(
title: Text('Permission Not Granted'),
content:
Text('The permission for photo library is not granted'),
actions: [
ElevatedButton(
onPressed: () => openAppSettings(),
child: Text('Ok'),
),
],
);
return CupertinoAlertDialog(
title: Text('Permission Not Granted'),
content:
Text('The permission for photo library is not granted'),
actions: [
ElevatedButton(
onPressed: () => openAppSettings(),
child: Text('Ok'),
),
],
);
});
} else if (status.isDenied) {
print('Permission Undetermined');
}
},
child: Padding(
padding: EdgeInsets.only(
top: 10.0,
bottom: 10.0,
),
child: Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.transparent,
border: Border.all(
style: BorderStyle.solid,
color: Colors.red,
),
),
child: pickedImage == null
? Icon(
Icons.add,
color: Colors.red,
)
: Image.file(
pickedImage!,
fit: BoxFit.contain,
),
),
),
);
}
ButtonTheme _addProductButton(BuildContext context) {
return ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.1,
child: ElevatedButton(
onPressed: imgStatus
? () async {
if (_formKey.currentState?.validate() == true) {
try {
Navigator.pop(context);
await addGroceryItemToToDb();
} catch (error) {
print(error);
}
}
}
: null,
child: Text(
'Add Product',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
Padding _writeDescription() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerDescription,
maxLines: 5,
inputFormatters: [
new LengthLimitingTextInputFormatter(
1450,
),
],
maxLength: 1450,
decoration: InputDecoration(
alignLabelWithHint: true,
isDense: true,
labelText: 'Description',
helperText: "Describe what you're selling in detail",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
Padding _conditionDropDown() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: conditionDropdownbuttonStyle(),
);
}
Widget conditionDropdownbuttonStyle() {
List<Text> pickerItems = [];
for (String condition in conditionList) {
pickerItems.add(Text(condition));
}
if (Platform.isIOS) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Condition',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
CupertinoPicker(
backgroundColor: Colors.white70,
useMagnifier: true,
itemExtent: 32.0,
diameterRatio: 2,
scrollController: FixedExtentScrollController(initialItem: 0),
magnification: 1.2,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
selectedCondition = conditionList[selectedIndex];
print(selectedCondition);
},
children: pickerItems,
),
],
);
}
List<DropdownMenuItem<String>> dropDownItem = [];
for (String condition in conditionList) {
print(condition);
var newItem = DropdownMenuItem<String>(
child: Text(condition),
value: condition,
);
dropDownItem.add(newItem);
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Condition',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 10.0,
),
Expanded(
child: DropdownButton<String>(
items: dropDownItem,
isExpanded: true,
value: selectedCondition,
hint: Text(
'Condition',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onChanged: (value) {
setState(() {
if (value != null) {
selectedCondition = value;
}
});
},
),
)
],
);
}
Padding _categoryDropDown() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: categoryDropdownbuttonStyle(),
);
}
Widget categoryDropdownbuttonStyle() {
List<Text> pickerItems1 = [];
for (String category in categoryList) {
pickerItems1.add(Text(category));
}
if (Platform.isIOS) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Category',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
CupertinoPicker(
backgroundColor: Colors.white70,
useMagnifier: true,
itemExtent: 32.0,
diameterRatio: 2,
scrollController: FixedExtentScrollController(initialItem: 0),
magnification: 1,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
selectedCategory = categoryList[selectedIndex];
print(selectedCategory);
},
children: pickerItems1,
),
],
);
}
List<DropdownMenuItem<String>> dropDownItem = [];
for (String category in categoryList) {
print(category);
var newItem = DropdownMenuItem<String>(
child: Text(category),
value: category,
);
dropDownItem.add(newItem);
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Category',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 10.0,
),
Expanded(
child: DropdownButton<String>(
items: dropDownItem,
isExpanded: true,
value: selectedCategory,
hint: Text(
'Category',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onChanged: (value) {
setState(() {
if (value != null) {
selectedCategory = value;}
});
},
),
)
],
);
}
Padding _giveitfree() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Give it away for free',
maxLines: 1,
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
switchButtonType(),
],
),
);
}
Widget _writePrice() {
if (_switchValue) {
return Container(
width: 0.0,
height: 0.0,
);
}
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerPrice,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
5,
),
FilteringTextInputFormatter.digitsOnly,
],
decoration: InputDecoration(
prefixIcon: Icon(Icons.attach_money),
isDense: true,
labelText: 'Price',
helperText: 'Set your Price',
hintText: 'Default Price: 0 \u0024',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
Padding _writeTitle() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
validator: (value) {
if (value != null) {
if (value.length < 5) {
return 'The title should be at least 5 characters';
}
return null;
};
return null;},
controller: controllerTitle,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
50,
),
],
decoration: InputDecoration(
prefixIcon: Icon(
Icons.title,
),
isDense: true,
labelText: 'Title*',
labelStyle: TextStyle(
color: Colors.red,
),
helperText: 'Describe your Product in few words',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
8.0,
),
),
),
),
);
}
Padding _writeLocation() {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 10.0,
),
child: TextFormField(
controller: controllerlocation,
maxLines: 1,
inputFormatters: [
new LengthLimitingTextInputFormatter(
50,
),
],
decoration: InputDecoration(
prefixIcon: Icon(
Icons.location_on,
),
suffixIcon: IconButton(
icon: Icon(Icons.near_me),
onPressed: getLocation,
),
isDense: true,
labelText: 'Location',
helperText: 'Eg: Austin,Texas',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
);
}
getLocation() async {
try {
await Permission.location.request();
var status = await Permission.location.status;
if (status.isGranted) {
print('Permission Granted');
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
print(position);
double latitude = position.latitude;
double longitude = position.longitude;
print('latitude: $latitude \n longitude: $longitude');
List<Placemark> placemark = await placemarkFromCoordinates(
latitude,
longitude,
);
setState(() {
print(placemark[0]);
controllerlocation.text =
('${placemark[0].locality},${placemark[0].administrativeArea},${placemark[0].country}')
.toString();
});
} else if (status.isDenied || status.isRestricted) {
print('Permission Denied');
Widget switchButtonType() {
if (Platform.isAndroid) {
return Switch(
value: _switchValue,
onChanged: (value) {
setState(
() {
_switchValue = value;
isReadOnly = _switchValue;
controllerPrice.text = '0';
print(_switchValue);
},
);
},
);
}
return CupertinoSwitch(
value: _switchValue,
onChanged: (value) {
setState(
() {
_switchValue = value;
isReadOnly = _switchValue;
controllerPrice.text = '0';
print(_switchValue);
},
You are filtering items that have isSold set to true but when adding you are adding with isSold set to false. Maybe you should change your filter to .where('isSold', isEqualTo: false)?

Flutter - Disable a button, not all buttons

I am getting a list from Firebase. The list loads as expected, However I have two issues.
1 - When the button in one item from the list is disabled, all the buttons in the other items also get disabled. I don't want this to happen. How can I get passed this?
2 - I am getting "positiveCount" and "negativeCount" from firebase RTDB. I want to get total (positiveCount + negativeCount) and then calculate the percentage of "positiveCount". (Example: positiveCount = 2, negativeCount = 2, percentage of positiveCount should be 50 percent). The problem is, ıf there is only one item that is loaded, it works perfectly. If there is more than one item loaded, I get an error.
Exception:
Exception has occurred.
UnsupportedError (Unsupported operation: Infinity or NaN toInt)
My Code:
import 'package:colour/colour.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// import 'package:shared_preferences/shared_preferences.dart';
class VaccineCenterList extends StatefulWidget {
const VaccineCenterList({key}) : super(key: key);
static const String idScreen = "VaccineCenterList";
#override
_VaccineCenterListState createState() => _VaccineCenterListState();
}
class _VaccineCenterListState extends State<VaccineCenterList> {
final databaseReference = FirebaseDatabase.instance.reference();
final firestoreInstance = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
List<Hospitals> driverList = [];
late String isTrueOrFalse = "False";
// // double percentageInt = 0.0;
int totalVotes = 0;
// int percentage = 0;
int positiveCount = 0;
int negativeCount = 0;
bool buttonPressed = true;
TextEditingController hospitalCountyEditingController =
TextEditingController();
Future<List<Hospitals>> getHospitalDetails() async {
try {
if ((hospitalCountyEditingController.text != "") &&
(hospitalCountyEditingController.text != " ")) {
databaseReference
.child("Hospitals")
.child(hospitalCountyEditingController.text)
.onValue
.listen(
(event) {
setState(
() {
var value = event.snapshot.value;
driverList = Map.from(value)
.values
.map((e) => Hospitals.fromJson(Map.from(e)))
.toList();
},
);
},
);
} else {}
} catch (e) {
}
return driverList;
}
calculatePositivePercentage(
positiveCount, negativeCount) {
// this method gets the number of "yes" and "no" votes. Then calculates the
// percentage of people who voted "yes".
// total = positiveCount + negativeCount;
// percentage = (positiveCount * 100) ~/ total;
totalVotes = positiveCount + negativeCount;
int percentage = positiveCount * 100;
double votePercentage = percentage / totalVotes;
return votePercentage;
}
#override
void initState() {
super.initState();
print("I'm in the vaccine list search screen");
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
centerTitle: true,
elevation: 0,
iconTheme: const IconThemeData(
color: Colors.black,
),
title: Text(
"Pamoja",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 35,
),
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Column(
children: [
Container(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: hospitalCountyEditingController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
style: BorderStyle.solid,
width: 1,
),
),
labelText: "Search County",
labelStyle: const TextStyle(
fontSize: 14.0,
color: Colors.blueGrey,
),
hintStyle: GoogleFonts.lexendMega(
color: Colors.grey,
fontSize: 10,
),
),
style: GoogleFonts.lexendMega(
fontSize: 14,
color: Colors.black,
),
),
),
ElevatedButton(
onPressed: () {
buttonPressed = false;
setState(() {
FocusScope.of(context).requestFocus(
FocusNode(),
);
driverList.clear();
if (hospitalCountyEditingController.text == "" ||
hospitalCountyEditingController.text == " ") {
isTrueOrFalse = "False";
} else {
isTrueOrFalse = "True";
}
});
getHospitalDetails();
},
child: Text(
"Search",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height,
// color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: driverList.isEmpty
? Center(
// child: CircularProgressIndicator(),
child: (isTrueOrFalse == "True")
? const CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Search for one of the counties below",
style: GoogleFonts.lexendMega()),
),
Text(
"Nairobi, Baringo, Busia, Bomet, Bungoma, Elgeyo Marakwet, Embu, Garissa, Homa Bay, Isiolo, Kajiado, Kakamega, Kericho, Kiambu, Kilifi, Kirinyaga, Kisii, Kisumu, Kitui, Kwale, Laikipia, Lamu, Machakos, Makueni, Mandera, Marsabit, Meru, Migori, Mombasa, Muranga, Nakuru, Nandi, Narok, Nyamira, Nyandarua, Nyeri, Samburu, Siaya County, Taita Taveta, Tana River County, Tharaka Nithi, Trans Nzoia, Turkana, Uasin Gishu, Vihiga, Wajir, West Pokot",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
],
),
)
: ListView.builder(
itemCount: driverList.length,
itemBuilder: (context, int index) {
final Hospitals hospitals = driverList[index];
final String hospitalLocaiton = hospitals.location;
final String hospitalPhone = hospitals.phone;
// final int totalVotes = hospitals.totalVotes;
final String hospitalName = hospitals.name;
// final String county = hospitals.county;
positiveCount = hospitals.positiveCount;
negativeCount = hospitals.negativeCount;
// final int percentage = positiveCount * 100;
// final double percentageInt =
// percentage / totalVotes;
// ignore: unused_local_variable
final double setpercentage =
calculatePositivePercentage(positiveCount, negativeCount);
**final percentageInt = setpercentage.toInt();**
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 0,
child: ExpansionTile(
title: Text(
hospitalName.toUpperCase(),
style: GoogleFonts.lexendMega(),
textAlign: TextAlign.center,
),
children: [
Column(
children: [
Container(
child: (hospitalPhone.isNotEmpty)
? ElevatedButton(
onPressed: () {
Clipboard.setData(
ClipboardData(
text: hospitalPhone,
),
);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.green,
content: Text(
"Number Copied",
textAlign:
TextAlign.center,
),
),
);
},
child: Text(
hospitalPhone,
textAlign: TextAlign.center,
style:
GoogleFonts.lexendMega(
fontSize: 13),
),
style:
ElevatedButton.styleFrom(
elevation: 0,
),
)
: const Text(""),
),
const SizedBox(
height: 5,
),
hospitalLocaiton.isNotEmpty
? Container(
padding:
const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius:
BorderRadius.circular(10),
),
child: Text(
hospitalLocaiton,
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
),
),
)
: Text(
hospitalLocaiton,
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
),
),
const SizedBox(
height: 10,
),
Text(
"$percentageInt% (percent) of voters say this hospital administer vaccines.",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.deepPurple[400],
),
),
const SizedBox(
height: 10,
),
const Divider(
// thickness: 1,
indent: 20,
endIndent: 20,
color: Colors.black87,
),
const SizedBox(
height: 10,
),
Text(
"Does this Hospital administer Vaccines?\n(To help the public, please vote only if you know.)",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
// Container(
// child: (positiveCount == 0)
// ? Text("Votes: $positiveCount")
// : Text("Votes: " +
// positiveCount.toString()),
// ),
Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onLongPress: buttonPressed
? () {
buttonPressed = false;
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors
.purpleAccent,
content: Text(
"Vote Removed",
textAlign:
TextAlign
.center,
),
),
);
undoPositiveIncrement(
hospitalName);
}
: null,
onPressed: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.greenAccent,
content: Text(
"Voted Yes",
textAlign:
TextAlign.center,
),
),
);
positiveIncrement(
hospitalName);
} : null,
child: Text(
"Yes - $positiveCount",
style: GoogleFonts
.lexendMega(),
),
style:
ElevatedButton.styleFrom(
primary: Colour("#87D68D"),
),
),
ElevatedButton(
onLongPress: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.purpleAccent,
content: Text(
"Vote Removed",
textAlign:
TextAlign.center,
),
),
);
undoNegativeIncrement(
hospitalName);
} : null,
onPressed: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content: Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
negativeIncrement(
hospitalName);
} : null,
child: Text(
"No - $negativeCount",
style: GoogleFonts
.lexendMega(),
),
style:
ElevatedButton.styleFrom(
primary: Colour("#E3655B"),
),
),
],
),
const SizedBox(
height: 10,
),
Text(
"Total No. of Votes: ",
style: GoogleFonts.lexendMega(
fontSize: 12),
),
const SizedBox(
height: 10,
),
Text(
"1 - To vote, tap once\n2 - To Undo vote, tap and hold",
style: GoogleFonts.lexendMega(
fontSize: 12,
),
textAlign: TextAlign.start,
),
const SizedBox(
height: 10,
),
],
),
],
),
],
),
),
);
},
),
),
),
],
),
),
),
);
}
}
class Hospitals {
final String name;
final String phone;
final String location;
// final String county;
final int positiveCount;
final int negativeCount;
// final int intPercentage;
// final int totalVotes;
Hospitals({
required this.name,
required this.phone,
required this.location,
// required this.county,
required this.positiveCount,
required this.negativeCount,
// required this.intPercentage,
// required this.totalVotes,
});
static Hospitals fromJson(Map<String, dynamic> json) {
return Hospitals(
name: json['HospitalName'],
phone: json['HospitalPhone'],
// county: json['county'],
location: json['HospitalAddres'],
positiveCount: json['poitiveCount'],
negativeCount: json['negativeCount'],
// intPercentage: json['intPercentage'],
// totalVotes: json['totalVotes']
);
}
}
Solution for issue 2:
calculatePositivePercentage(positiveCount, negativeCount) {
// this method gets the number of "yes" and "no" votes. Then calculates the
// percentage of people who voted "yes".
double votePercentage = 0;
if (positiveCount == 0 && negativeCount == 0) {
try {
return votePercentage.toInt();
} catch (e) {
print(e);
}
} else {
try {
totalVotes = positiveCount + negativeCount;
int percentage = positiveCount * 100;
votePercentage = percentage / totalVotes;
return votePercentage.toInt();
} catch (e) {
print(e);
}
}
}
To prevent all buttons to be disabled instead of
bool buttonPressed = true;
use
List<bool> buttonPressed = [true];
and your 2nd error is because may be you are not getting an int value from the response try
int.parse();
to parse a String to int

Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct)

#override
void initState() {
super.initState();
_loadData();
}
void _loadData() async {
await StorageUtil.getInstance();
String cookie = StorageUtil.getString('sess');
String page = currentPage.toString();
if (cookie != null) {
ApiService.getEstimateList(cookie, page, myAllestimate, search)
.then((value) {
if (value.data != null) {
if (count < _totalRecords) {
setState(() {
invoicelist.addAll(value.data);
print(value.data);
_totalRecords = value.recordsTotal;
});
print(
'List size is $count and TotalRecord - ${value.recordsTotal} , TotalFiltered - ${value.recordsFiltered}');
}
}
});
}
}
Future<bool> _loadMoreData() async {
print('_loadMoreData()');
await Future.delayed(Duration(seconds: 0, milliseconds: 1000));
currentPage += 1;
_loadData();
return true;
}
Future<void> _refresh() async {
currentPage = 1;
_totalRecords = 100;
invoicelist.clear();
_loadData();
}
getCustomFormattedDateTime(String givenDateTime, String dateFormat) {
// dateFormat = 'MM/dd/yy';
final DateTime docDateTime = DateTime.parse(givenDateTime);
return DateFormat(dateFormat).format(docDateTime);
}
onSearchTextChanged(String text) async {
String search = text.toLowerCase();
searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
if (_selectedIndex == 0) {
myAllestimate = 'my';
} else {
myAllestimate = 'all';
}
currentPage = 1;
String cookie = StorageUtil.getString('sess');
String page = currentPage.toString();
if (cookie != null) {
ApiService.getEstimateList(cookie, page, myAllestimate, search)
.then((value) {
if (value.data.length > 0) {
if (count < _totalRecords) {
setState(() {
searchResult.addAll(value.data);
_totalRecords = value.recordsTotal;
});
print(
'searchResult size is $count and TotalRecord - ${value.recordsTotal} , TotalFiltered - ${value.recordsFiltered}');
}
} else {
searchResult.clear();
setState(() {});
}
});
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new CatalogService(pageDirection: pageDirection)));
},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.add,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: _bottomTab(),
appBar: new AppBar(
title: appBarTitle,
actions: [
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
controller: controller,
onChanged: onSearchTextChanged,
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
prefixIcon:
new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white)),
);
} else {
controller.clear();
searchResult.clear();
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text("Manage Estimate");
}
});
},
),
],
),
body: Stack(
children: [
Center(
child: Visibility(
visible: (search.length > 0 && searchResult.length > 0)
? true
: false,
child: Text('No Data Found'),
),
),
Container(
child: searchResult.length != 0 || controller.text.isNotEmpty
? searchResults()
: buildResults()),
],
));
}
Widget searchResults() {
return RefreshIndicator(
child: LoadMore(
isFinish: count >= _totalRecords,
onLoadMore: _loadMoreData,
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
final item = searchResult[index];
String date = item.invDate.toString();
String strDate = getCustomFormattedDateTime(date, 'dd-MM-yyyy');
return Container(
padding: EdgeInsets.only(
top: 10.0, left: 20.0, right: 20.0, bottom: 10.0),
child: GestureDetector(
onTap: () {
print(searchResult[index].id);
String bmaster = StorageUtil.getString('bmaster');
String cookie = StorageUtil.getString('sess');
String id = searchResult[index].id.toString();
String mobile = searchResult[index].mobile.toString();
int custId = invoicelist[index].custId;
var weburl = '', pdfUrl;
ApiService.viewInvoice(cookie, id, bmaster, 'estimate')
.then((value) {
if (value != null) {
var result = jsonDecode(value);
if (result['status'].toString() == '1') {
var decode = Uri.decodeFull(result['url']);
var pdf_url = Uri.decodeFull(result['pdf_url']);
pdfUrl = pdf_url.toString();
weburl = decode.toString();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebViewContainer(
weburl, 'Estimate', pdfUrl, mobile, id, custId),
),
);
}
}
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: ScreenUtil().setSp(150),
child: Text(
item.custName,
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontFamily: 'montserratbold',
fontWeight: FontWeight.w500,
),
),
),
Padding(
padding:
EdgeInsets.only(top: 2.0, bottom: 2.0)),
Text(
"EST-" + item.invNumber,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
Padding(padding: EdgeInsets.only(top: 2.0)),
Text(
strDate,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
// Padding(padding: EdgeInsets.only(top: 2.0)),
// Text(
// 'Party Balance-' +
// item.p.toString(),
// style: TextStyle(
// fontSize: 12.0, color: Colors.black),
// ),
],
),
Column(
children: <Widget>[
Text(
'Rs.' + item.totalAmt,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
Padding(padding: EdgeInsets.only(top: 10.0)),
Container(
width: ScreenUtil().setSp(100),
height: ScreenUtil().setSp(25),
decoration: BoxDecoration(
color:
Color(0xffffcdd2), // border: Border.all(
// color: Colors.red[500],
// ),
borderRadius:
BorderRadius.all(Radius.circular(5))),
child: Container(
alignment: Alignment.center,
child: Text(
(item.status == 0) ? 'Paid' : 'Not Paid',
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'montserrat',
fontSize: ScreenUtil().setSp(12),
color: Colors.red),
),
),
),
],
),
],
),
Padding(padding: EdgeInsets.only(top: 15)),
Container(
margin: EdgeInsets.only(top: 5, bottom: 5),
child: const Divider(
height: 2,
thickness: 1,
),
),
// Text(item.custName),
],
),
),
);
},
itemCount: searchResult.length,
),
whenEmptyLoad: true,
delegate: DefaultLoadMoreDelegate(),
textBuilder: DefaultLoadMoreTextBuilder.english,
),
onRefresh: _refresh,
);
}
Widget buildResults() {
return RefreshIndicator(
child: LoadMore(
isFinish: count >= _totalRecords,
onLoadMore: _loadMoreData,
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
final item = invoicelist[index];
String date = item.invDate.toString();
String strDate = getCustomFormattedDateTime(date, 'dd-MM-yyyy');
return Container(
padding: EdgeInsets.only(
top: 10.0, left: 20.0, right: 20.0, bottom: 10.0),
child: GestureDetector(
onTap: () {
print(invoicelist[index].id);
String bmaster = StorageUtil.getString('bmaster');
String cookie = StorageUtil.getString('sess');
String id = invoicelist[index].id.toString();
String estNumber = invoicelist[index].invNumber.toString();
String mobile = invoicelist[index].mobile.toString();
int custId = invoicelist[index].custId;
var weburl = '', pdfUrl;
ApiService.viewInvoice(cookie, id, bmaster, 'estimate')
.then((value) {
if (value != null) {
var result = jsonDecode(value);
if (result['status'].toString() == '1') {
var decode = Uri.decodeFull(result['url']);
var pdf_url = Uri.decodeFull(result['pdf_url']);
pdfUrl = pdf_url.toString();
weburl = decode.toString();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebViewContainer(weburl,
'Estimate', pdfUrl, mobile, estNumber, custId),
),
);
}
}
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: ScreenUtil().setSp(150),
child: Text(
item.custName,
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontFamily: 'montserratbold',
fontWeight: FontWeight.w500,
),
),
),
Padding(
padding:
EdgeInsets.only(top: 2.0, bottom: 2.0)),
Text(
"EST-" + item.invNumber,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
Padding(padding: EdgeInsets.only(top: 2.0)),
Text(
strDate,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
// Padding(padding: EdgeInsets.only(top: 2.0)),
// Text(
// 'Party Balance-' +
// item.p.toString(),
// style: TextStyle(
// fontSize: 12.0, color: Colors.black),
// ),
],
),
Column(
children: <Widget>[
Text(
'Rs.' + item.totalAmt,
style: TextStyle(
fontSize: ScreenUtil().setSp(12.0),
fontFamily: 'montserrat',
color: Colors.black),
),
Padding(padding: EdgeInsets.only(top: 10.0)),
Container(
width: ScreenUtil().setSp(100),
height: ScreenUtil().setSp(25),
decoration: BoxDecoration(
color:
Color(0xffffcdd2), // border: Border.all(
// color: Colors.red[500],
// ),
borderRadius:
BorderRadius.all(Radius.circular(5))),
child: Container(
alignment: Alignment.center,
child: Text(
'Not Paid',
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'montserrat',
fontSize: ScreenUtil().setSp(12),
color: Colors.red),
),
),
),
],
),
],
),
Padding(padding: EdgeInsets.only(top: 15)),
Container(
margin: EdgeInsets.only(top: 5, bottom: 5),
child: const Divider(
height: 2,
thickness: 1,
),
),
// Text(item.custName),
],
),
),
);
},
itemCount: count,
),
whenEmptyLoad: true,
delegate: DefaultLoadMoreDelegate(),
textBuilder: DefaultLoadMoreTextBuilder.english,
),
onRefresh: _refresh,
);
}
I am implementing search in my loadmore listview which is causing error when I am searching data from API.
Error:
Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
E/flutter (21599): Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.
you can check for mounted before call setState()
if (mounted) {
setState(() => {});
}
bool mounted
Whether this State object is currently in a tree.
After creating a State object and before calling initState, the
framework "mounts" the State object by associating it with a
BuildContext. The State object remains mounted until the framework
calls dispose, after which time the framework will never ask the State
object to build again.
It is an error to call setState unless mounted is true.
https://api.flutter.dev/flutter/widgets/State/mounted.html

When routing to another page I get "There are multiple heroes that share the same tag within a subtree"

I am trying to navigate from one screen to another with route. When I hit the button for the page to move to the route provided I get the error:
I/flutter ( 8790): Another exception was thrown: There are multiple heroes that share the same tag within a subtree.
Sharing with you the source code:
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_counter/flutter_counter.dart';
import 'package:gender_selection/gender_selection.dart';
import 'package:group_chats/addContactUI.dart';
import 'package:group_chats/addPhone.dart';
import 'package:group_chats/letGoUI.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Animation/FadeAnimation.dart';
import 'Model/insertUserModel.dart';
class AddProfileUI extends StatefulWidget {
final List<String> listFriends;
final String phone;
AddProfileUI(this.listFriends, this.phone);
#override
_AddProfileUIState createState() => _AddProfileUIState();
}
class _AddProfileUIState extends State<AddProfileUI> {
File _image;
final picker = ImagePicker();
final _formKey = GlobalKey<FormState>();
String name = "";
String city = "";
TextEditingController dobController = TextEditingController();
bool single = false;
Gender gender;
final _scaffoldKey = GlobalKey<ScaffoldState>();
int defaultValue = 18;
List<String> selectedContact;
SharedPreferences prefs;
bool _loading = true;
Future initPrefs() async {
prefs = await SharedPreferences.getInstance();
}
uploadImage(String userId) async {
try {
FormData formData = new FormData.fromMap({
"file":
await MultipartFile.fromFile(_image.path, filename: "$userId.jpg"),
});
var response = await Dio().post(
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/upload_profile/$userId",
data: formData);
if (response.statusCode == 200)
return response.data;
else
return null;
} catch (e) {
print(e.toString());
return null;
}
}
Future<InsertUserModel> insertData() async {
try {
for (int i = 0; i < selectedContact.length; i++) {
if (selectedContact[i][0] == "0") {
selectedContact[i] = selectedContact[i].replaceRange(0, 1, "+972");
}
}
var body = jsonEncode({
"gender": gender.index == 0 ? "male" : "female",
"city": city,
"last_login": {},
"friends": selectedContact ?? [],
"single": single,
"name": name,
"phone_number": widget.phone,
"age": defaultValue
});
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/${AddPhoneUI.uid}";
final response = await http.post(apiUrl,
headers: {"content-type": "application/json"}, body: body);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
}
}
getUserData() async {
try {
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/";
final response = await http.get(apiUrl);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red,
content: Text('Error: ${e.toString()}'),
duration: Duration(milliseconds: 2500),
));
}
}
Future<void> _selectStartingDate(BuildContext context) async {
DateTime selectedDate = DateTime.now();
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1950),
lastDate: DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day),
);
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
dobController.text = selectedDate.year.toString() +
"-" +
selectedDate.month.toString() +
"-" +
selectedDate.day.toString();
});
}
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
showPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
shape:
OutlineInputBorder(borderRadius: BorderRadius.circular(14.0)),
content: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 20.0,
),
Text(
"My Profile",
style: TextStyle(
fontSize: 27.0, fontWeight: FontWeight.w600),
),
SizedBox(
height: 30.0,
),
RichText(
text: TextSpan(
text: "Your friends will be able to\nsee ",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'only',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: 'your picture and\name.'),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Other fields are used for\n",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'research issues',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: "only."),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Please fill all the fields.",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
)),
SizedBox(
height: 80.0,
),
MaterialButton(
shape: OutlineInputBorder(
borderSide: BorderSide(width: 1.0)),
color: Colors.white38,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Ok, got it",
style: TextStyle(fontSize: 18.0),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
));
}
#override
void initState() {
super.initState();
selectedContact = widget.listFriends;
initPrefs();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddContactUI(),
)).then((value) {
setState(() {
selectedContact = value;
});
});
},
child: Column(
children: [
Icon(
Icons.supervisor_account,
size: 40.0,
),
Text("Add Friends"),
],
),
)
],
),
),
Container(
child: GestureDetector(
onTap: () async {
await getImage();
},
child: CircleAvatar(
radius: 60.0,
backgroundImage: _image != null
? Image.file(_image).image
: Image.asset("assets/empty.png").image,
backgroundColor: Colors.transparent,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FadeAnimation(
1.7,
Form(
key: _formKey,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Color(0xff5E17EB).withOpacity(0.3),
blurRadius: 20,
offset: Offset(0, 10),
)
]),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
child: TextFormField(
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) =>
FocusScope.of(context).nextFocus(),
onChanged: (val) {
setState(() {
name = val;
});
},
validator: (val) =>
val.isEmpty ? "Enter Name" : null,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Name",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
padding: EdgeInsets.all(10),
child: TextFormField(
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
onChanged: (val) {
setState(() {
city = val;
});
},
validator: (val) {
if (val.isEmpty) return "Enter City";
// if (val.length < 6)
// return "Password should be at least 6 characters";
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
hintText: "City",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
height: 140.0,
padding: EdgeInsets.all(10),
child: GenderSelection(
selectedGender: gender,
maleText: "", //default Male
femaleText: "", //default Female
linearGradient: LinearGradient(colors: [
Colors.indigo,
Colors.black
]), //List: [Colors.indigo, Colors.black]
selectedGenderIconBackgroundColor:
Colors.indigo, // default red
checkIconAlignment:
Alignment.centerRight, // default bottomRight
selectedGenderCheckIcon:
null, // default Icons.check
onChanged: (Gender gender) {
this.gender = gender;
print(this.gender);
},
equallyAligned: true,
animationDuration: Duration(milliseconds: 400),
isCircular: true, // default : true,
isSelectedGenderIconCircular: true,
opacityOfGradient: 0.6,
padding: const EdgeInsets.all(3),
size: 120, //default : 120
),
),
SizedBox(
height: 10.0,
),
Row(
children: [
Checkbox(
value: single,
onChanged: (value) {
setState(() {
single = !single;
});
},
),
Text(
"Are you Single?",
style: TextStyle(fontSize: 16.0),
)
],
),
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Age:",
style: TextStyle(fontSize: 18.0),
),
Counter(
initialValue: defaultValue,
buttonSize: 35.0,
textStyle: TextStyle(fontSize: 25.0),
minValue: 0,
color: Colors.black,
maxValue: 80,
step: 1,
decimalPlaces: 0,
onChanged: (value) {
// get the latest value from here
setState(() {
defaultValue = value;
});
},
),
],
),
),
],
),
),
),
),
),
SizedBox(
height: 20.0,
),
FadeAnimation(
1.9,
MaterialButton(
shape: OutlineInputBorder(borderSide: BorderSide(width: 1.0)),
color: Colors.black,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Next",
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
),
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
InsertUserModel result = await insertData();
// var imageResult = await uploadImage(result.id);
print(result.data[0].id);
if (_image != null) {
await uploadImage(result.data[0].id);
}
setState(() {
_loading = false;
});
if (result != null) {
await prefs.setString("userID", result.data[0].id);
final snackBar = SnackBar(
content: Text(
result.message,
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.green,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LetGoUI(result.data[0].id),
));
} else {
final snackBar = SnackBar(
content: Text(
"Here is some error, please try again later!",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.red,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
},
),
)
],
),
),
),
);
}
}
I really don't understand what is the problem because I'm not using any Heros and not have double FloatingActionButton.
How do I solve this?
Thanks
There might be problem with showing snackbar while navigating. you should remove that problem by calling following method before navigating.
void removeSnackBarCallsBeforeNavigation() {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
}