Flutter Gesture Detector ontap throws Stack Overflow error - flutter

I have a controller in a controller.dart file and I'm using it in view.dart file to login a user but clicking on the gesture detector throws a stack overflow error. I've tried many things and looked all over but can't seem to understand what's wrong
controller.dart
class SigninController extends GetxController {
// SigninController();
final state = SigninController();
final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['openid']);
// ignore: unused_element
Future<void> handleSignIn(String type) async {
//number 1 = email, number 2 = google, number 3 = facebook, number 4 = apple, number 5 = phone
try {
if (type == "phone") {
if (kDebugMode) {
print("Logging in with phone");
}
} else if (type == "google") {
var user = await _googleSignIn.signIn();
if (user != null) {
String? displayName = user.displayName;
String email = user.email;
String id = user.id;
String photo = user.photoUrl ?? "assets/icons/google.png";
LoginRequestEntity loginPanelListRequestEntity = LoginRequestEntity();
loginPanelListRequestEntity.avatar = photo;
loginPanelListRequestEntity.name = displayName;
loginPanelListRequestEntity.avatar = photo;
loginPanelListRequestEntity.open_id = id;
loginPanelListRequestEntity.type = 2;
}
} else {
if (kDebugMode) {
print("Login type not defined");
}
}
} catch (e) {
if (kDebugMode) {
print("Login error $e");
}
}
}
}
concerned widget from view.dart file
Widget _buildThirdPartyLogin(String loginType, String logo) {
return GestureDetector(
onTap: () => controller.handleSignIn(loginType),
child: Container(
width: 295.w,
height: 44.h,
margin: EdgeInsets.only(bottom: 20.h),
decoration: BoxDecoration(
color: AppColors.primaryBackground,
borderRadius: const BorderRadius.all(Radius.circular(5)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 2,
offset: const Offset(0, 1))
]),
child: Row(children: [
Container(
padding: EdgeInsets.only(left: 40.w, top: 5.w, bottom: 5.w),
child: Image.asset("assets/icons/$logo.png"),
),
Container(
padding: EdgeInsets.only(left: 20.w),
child: Text(
"Sign up with $loginType",
style: TextStyle(
color: AppColors.primaryText,
fontSize: 16.sp,
fontWeight: FontWeight.bold),
),
)
]),
),
);
}
Error produced
Handler: "onTap"
Recognizer: TapGestureRecognizer#4f5fc
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(205.4, 249.4)
finalLocalPosition: Offset(170.0, 21.2)
button: 1
sent tap down

Use this:
Changes are sizing parameter that you have used
Widget _buildThirdPartyLogin(String loginType, String logo) {
return GestureDetector(
onTap: () => controller.handleSignIn(loginType),
child: Container(
width: 295,
height: 44,
margin: EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: AppColors.primaryBackground,
borderRadius: const BorderRadius.all(Radius.circular(5)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 2,
offset: const Offset(0, 1))
]),
child: Row(children: [
Container(
padding: EdgeInsets.only(left: 40, top: 5, bottom: 5),
child: Image.asset("assets/icons/$logo.png"),
),
Container(
padding: EdgeInsets.only(left: 20),
child: Text(
"Sign up with $loginType",
style: TextStyle(
color: AppColors.primaryText,
fontSize: 16,
fontWeight: FontWeight.bold),
),
)
]),
),
);
}

Related

Not being able to read a Collection

I have my flutter app connected to my firebase proyect and im having trouble logging in, since with my code im not being able to read the collection i created
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
TextEditingController idController = TextEditingController();
TextEditingController passController = TextEditingController();
double screenHeight = 0;
double screenWidth = 0;
Color primary = const Color(0xffeef444c);
late SharedPreferences sharedPreferences;
get HomeScreen => null;
#override
Widget build(BuildContext context) {
final bool isKeyboardVisible =
KeyboardVisibilityProvider.isKeyboardVisible(context);
screenHeight = MediaQuery.of(context).size.height;
screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
isKeyboardVisible
? SizedBox(
height: screenHeight / 16,
)
: Container(
height: screenHeight / 2.5,
width: screenWidth,
decoration: BoxDecoration(
color: primary,
borderRadius: const BorderRadius.only(
bottomRight: Radius.circular(70),
),
),
child: Center(
child: Icon(
Icons.person,
color: Colors.white,
size: screenWidth / 5,
),
),
),
Container(
margin: EdgeInsets.only(
top: screenHeight / 15,
bottom: screenHeight / 20,
),
child: Text(
"Login",
style: TextStyle(
fontSize: screenWidth / 18,
fontFamily: "NexaBold",
),
),
),
Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.symmetric(
horizontal: screenWidth / 12,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
fieldTitle("Employee ID"),
customField("Enter your employee id", idController, false),
fieldTitle("Password"),
customField("Enter your password", passController, true),
GestureDetector(
onTap: () async {
FocusScope.of(context).unfocus();
String id = idController.text.trim();
String password = passController.text.trim();
if (id.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Employee id is still empty!"),
));
} else if (password.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Password is still empty!"),
));
} else {
QuerySnapshot snap = await FirebaseFirestore.instance
.collection("Employee")
.where('id', isEqualTo: id)
.get();
try {
if (password == snap.docs[0]['password']) {
sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences
.setString('employeeId', id)
.then((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomeScreen));
});
} else {
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(
content: Text("Password is not correct!"),
));
}
} catch (e) {
String error = " ";
if (e.toString() ==
"RangeError (index): Invalid value: Valid value range is empty: 0") {
setState(() {
error = "Employee id does not exist!";
});
} else {
setState(() {
error = "Error occurred!";
});
}
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(error),
));
}
}
},
child: Container(
height: 60,
width: screenWidth,
margin: EdgeInsets.only(top: screenHeight / 40),
decoration: BoxDecoration(
color: primary,
borderRadius: const BorderRadius.all(Radius.circular(30)),
),
child: Center(
child: Text(
"LOGIN",
style: TextStyle(
fontFamily: "NexaBold",
fontSize: screenWidth / 26,
color: Colors.white,
letterSpacing: 2,
),
),
),
),
)
],
),
),
],
),
);
}
Widget fieldTitle(String title) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
child: Text(
title,
style: TextStyle(
fontSize: screenWidth / 26,
fontFamily: "NexaBold",
),
),
);
}
Widget customField(
String hint, TextEditingController controller, bool obscure) {
return Container(
width: screenWidth,
margin: EdgeInsets.only(bottom: 12),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10,
offset: Offset(2, 2),
),
],
),
child: Row(
children: [
Container(
width: screenWidth / 6,
child: Icon(
Icons.person,
color: primary,
size: screenWidth / 15,
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(right: screenWidth / 12),
child: TextFormField(
controller: controller,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: screenHeight / 35,
),
border: InputBorder.none,
hintText: hint,
),
maxLines: 1,
obscureText: obscure,
),
),
)
],
),
);
}
}
i have a collection called "Employee" with 2 parameters being "id" and "password". Please help and thanks in advance. im getting this error
if (e.toString() == > "RangeError (index): Invalid value: Valid value range is empty: 0") { setState(() { error = "Employee id does not exist!"; > });
which i think it means Im not being able to read the specific Collection, tried enabling internet connection in Android manifest but still not working`

How to fix "Bad State:No element " flutter sharedPreference?

In my code fetching word from firebase and the user can select words and if the user selects a word and after deselect that then display and save firebase that also. And when the user selects a word then colour also.
I want to add sharedPrefences for that.
Ex: if the user selects words and clicks the next button and after closes the app and reopens later then should save the selected words and deselected words and then colour only selected words.
image
code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:shared_preferences/shared_preferences.dart';
class uitry extends StatefulWidget {
const uitry({Key? key}) : super(key: key);
#override
State<uitry> createState() => _uitryState();
}
class _uitryState extends State<uitry> {
//list
List<Words12> wordList = [];
//collection path
Future<List<Words12>> fetchRecords() async {
var records = await FirebaseFirestore.instance
.collection('12words')
.where("categoryName", isEqualTo: "Objects12")
.get();
return mapRecords(records);
}
List<Words12> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _wordList =
records.docs.map((data) => Words12.fromJson(data.data())).toList();
return _wordList;
}
#override
void initState() {
super.initState();
dropdownValueselectedWord = selectedWord.first;
checkValueSelectedWord();
dropdownValueDeselectedWord = deSelectedWord?.first;
checkValueDeselectedWord();
}
List<String> selectedWord = [];
String? dropdownValueselectedWord = "";
checkValueSelectedWord() {
_getDataSelectedWord();
}
_saveDataSelectedWord(String dropdownValueSelectedWord) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString(
"SelectedWordObject", dropdownValueSelectedWord);
}
_getDataSelectedWord() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueselectedWord =
sharedPreferences.getString("SelectedWordObject") ?? selectedWord.first;
setState(() {});
}
List<String>? deSelectedWord = [];
String? dropdownValueDeselectedWord = "";
checkValueDeselectedWord() {
_getDataDeselectedWord();
}
_saveDataDeselectedWord(String dropdownValueDeselectedWord) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString(
"SelectedWordObject", dropdownValueDeselectedWord);
}
_getDataDeselectedWord() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueselectedWord =
sharedPreferences.getString("SelectedWordObject") ??
deSelectedWord?.first;
setState(() {});
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(Config.app_background4), fit: BoxFit.fill),
),
child: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: ListTile(
leading: GestureDetector(
child: const Icon(
Icons.arrow_back_ios_new_sharp,
color: Colors.black,
size: 24.0,
),
onTap: () => Navigator.pop(context),
),
title: const Padding(
padding: EdgeInsets.only(top: 32, right: 35),
child: Text(
"Under 18 months",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.00,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
const SizedBox(
height: 00,
),
Padding(
padding: const EdgeInsets.only(top: 1, right: 0),
child: Column(
children: [
Material(
color: HexColor('#E92F54').withOpacity(0.9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0).copyWith(
topLeft: const Radius.circular(28.0),
topRight: const Radius.circular(28.0),
),
),
child: SizedBox(
width: width * 0.94,
height: height * 0.062,
child: Column(
children: const <Widget>[
SizedBox(
height: 6.5,
),
Text('Understanding',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 16.0)),
Text('Object',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 15.0))
],
),
),
),
Material(
color: HexColor('#FFFBFB').withOpacity(0.7),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2).copyWith(
bottomLeft: const Radius.circular(28.0),
bottomRight: const Radius.circular(28.0),
),
),
child: SizedBox(
width: width * 0.94,
height: height * 0.30, //white box height
child: Column(
children: [
SizedBox(
height: height * 0.18,
child: SingleChildScrollView(
child: Column(
//chip words
children: <Widget>[
const SizedBox(height: 10),
FutureBuilder<List<Words12>>(
future: fetchRecords(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text(
'Error: ${snapshot.error}');
} else {
wordList = snapshot.data ?? [];
return Wrap(
children: wordList.map(
(word) {
bool isSelected = false;
if (selectedWord!.contains(
word.wordName)) {
isSelected = true;
}
return GestureDetector(
onTap: () {
if (!selectedWord!
.contains(
word.wordName)) {
if (selectedWord!
.length <
50) {
selectedWord!.add(
word.wordName);
deSelectedWord!
.removeWhere(
(element) =>
element ==
word.wordName);
setState(() {});
print(selectedWord);
}
} else {
selectedWord!.removeWhere(
(element) =>
element ==
word.wordName);
deSelectedWord!
.add(word.wordName);
setState(() {
// selectedHobby.remove(hobby);
});
print(selectedWord);
print(deSelectedWord);
}
},
child: Container(
margin: const EdgeInsets
.symmetric(
horizontal: 5,
vertical: 4),
child: Container(
padding:
const EdgeInsets
.symmetric(
vertical: 5,
horizontal: 12),
decoration: BoxDecoration(
color: isSelected
? HexColor(
'#3A97FF')
: HexColor(
'#D9D9D9'),
borderRadius:
BorderRadius
.circular(
18),
border: Border.all(
color: isSelected
? HexColor(
'#3A97FF')
: HexColor(
'#D9D9D9'),
width: 1)),
child: Text(
word.wordName,
style: TextStyle(
color: isSelected
? Colors.black
: Colors
.black,
fontSize: 14,
fontWeight:
FontWeight
.w700),
),
),
),
);
},
).toList(),
);
}
}),
],
),
),
),
],
),
),
),
],
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.only(top: 20, left: 0, bottom: 0),
child: Center(
child: SizedBox(
width: 160.0,
height: 35.0,
child: ElevatedButton(
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(
color: Colors.blueAccent,
),
),
),
),
onPressed: displayMessage,
child: const Text("next"),
),
),
),
),
],
),
))),
),
);
}
void displayMessage() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);
final sp = context.read<SignInProvider>();
FirebaseFirestore.instance.collection("objects").doc(sp.uid).set({
"speackSE": selectedWord,
"speackUN": deSelectedWord,
});
_saveDataSelectedWord(dropdownValueselectedWord!);
_saveDataDeselectedWord(dropdownValueDeselectedWord!);
}
}
Bad State: No Element error is thrown when you're trying to access an element in an iterable at a location that does not exist. Like accessing the first or last element of the list (using the List getters like .first, .last, etc.)
You're using selectedWord.first in case the required data is not found in the prefs. Most probably, there's no item in the list which is the reason for the error.
Check all the places where you've used .first for empty lists. Make sure that the lists are not empty before calling these getters.

Flutter How can I save my date and Boolean value in Share preferences?

This is my output
all these functions are works excellent. But I tried to add sharedPrefence to these dropdowns, select birthday and to the checkbox. But both dropdowns work perfectly, When I select something in the dropdown and click the next button and close the app and reopen again then shows the words that are selected at the last. But after that, I tried to add sharedPrefence to datePicker and thin "Are you agree " check box but then shows some errors. I have no idea how to solve that.
EX:- In this, I used a date picker, Agree checkbox and in there shows "Birthday" word as an initial date and check box is unselecting, when the click selects the button then shows the dates and pick date and can select check box then value is true, That works perfectly. But I wanna add shared Preferences to this When added that, after the selected word and close the app and reopened again then should show the date and check box value true that is selected at the last.
my full code.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class FamilyDetailsScreen extends StatefulWidget {
#override
State<FamilyDetailsScreen> createState() => _FamilyDetailsScreenState();
}
class _FamilyDetailsScreenState extends State<FamilyDetailsScreen> {
// 1st dropdown button
#override
void initState() {
super.initState();
dropdownValueMembers = items.first;
dropdownValueNumber = number.first;
dropdownValueBirthday = birthday.first;
dropdownValueBirthday = Agree.first;
checkValueMembers();
checkValueNumber();
checkValueBirthday();
checkValueAgree();
}
String? dropdownValueMembers;
// List of items in our dropdown menu
List<String> items = [
'howmany',
'one',
'two',
'three ',
'four',
'5 or more'
];
checkValueMembers() {
_getData();
}
_saveData(String dropdownValueMembersShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data", dropdownValueMembersShared);
}
_getData() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueMembers = sharedPreferences.getString("data") ?? items.first;
setState(() {});
}
// 2nd dropdown button
// data which child
String? dropdownValueNumber;
// // List of items in our dropdown menu
List<String> number = ['which', '1 st', '2 nd', '3 rd ', '4 th ', '5 th'];
//IF "dropdownValueMembers" is empty pass "which" word as a initial value if al ready selected then pass the shared preference value
checkValueNumber() {
_getDataNumber();
}
_saveDataNumbers(String dropdownValueNumberShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data2", dropdownValueNumberShared);
}
_getDataNumber() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueNumber = sharedPreferences.getString("data2") ?? number.first;
setState(() {});
}
//date picker
DateTime? selectedDate;
DateTime now = new DateTime.now();
void showDatePicker() {
DateTime mindate = DateTime(now.year - 2, now.month, now.day - 29);
DateTime maxdate = DateTime(now.year - 1, now.month, now.day);
showCupertinoModalPopup(
context: context,
builder: (BuildContext builder) {
return Container(
height: MediaQuery.of(context).copyWith().size.height * 0.25,
color: Colors.white,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: mindate,
onDateTimeChanged: (value) {
if (value != null && value != selectedDate) {
setState(() {
selectedDate = value;
});
}
},
maximumDate: maxdate,
minimumDate: mindate,
),
);
});
}
String? dropdownValueBirthday;
List<String> birthday = [
'Birthday',
];
//sharedPreferences birthday
checkValueBirthday() {
_getDataBirthday();
}
_saveDataBirthday(String dropdownValueBirthdayShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("dataBirthday", dropdownValueBirthdayShared);
}
_getDataBirthday() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueBirthday =
sharedPreferences.getString("dataBirthday") ?? birthday.first;
setState(() {});
}
//////////////////////////////////
// are you agree button
//boolean value (are you agree)
bool isChecked = false;
checkValueAgree() {
_getDataAgree();
}
_saveDataAgree(String dropdownValueAgreeShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setBool("Agree", dropdownValueAgreeShared);
}
_getDataAgree() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueNumber = sharedPreferences.getBool("Agree") ?? isChecked.first;
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: <Widget>[
const Text(
'family details',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.00,
fontWeight: FontWeight.w700,
),
),
const SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 15),
child: Row(
children: <Widget>[
const Icon(
Icons.brightness_1,
color: Colors.black,
size: 10.0,
),
const Padding(
padding: EdgeInsets.only(left: 13),
child: Text(
"Number of children",
style:
TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
),
),
],
),
),
const SizedBox(
height: 25,
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 2),
child: Container(
height: 25,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueMembers,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: items.map((String data) {
return DropdownMenuItem(
value: data,
child: SizedBox(
height: 15,
width: 120.0, // for example
child: Text(data,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newValue) {
setState(
() {
dropdownValueMembers = newValue!;
},
);
},
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text('Which child'),
),
Padding(
padding: const EdgeInsets.only(left: 100, right: 0, top: 20),
child: Container(
height: 30,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueNumber,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: number.map((String number) {
return DropdownMenuItem(
value: number,
child: SizedBox(
height: 17,
width: 120.0, // for example
child: Text(number,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newNumber) {
setState(
() {
dropdownValueNumber = newNumber!;
},
);
},
),
),
),
],
),
const SizedBox(
height: 60,
),
Padding(
padding: const EdgeInsets.only(left: 15),
child: Row(
children: <Widget>[
const Icon(
Icons.brightness_1,
color: Colors.black,
size: 10,
),
const Padding(
padding: EdgeInsets.only(left: 15.0),
child: Text("birthday",
style: TextStyle(
fontSize: 16.0,
)),
),
Padding(
padding: const EdgeInsets.only(left: 25.0),
child: SizedBox(
width: 110.0,
height: 25.0,
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
),
child: Center(
child: Text(
selectedDate == null
? (dropdownValueBirthday ?? birthday.first)
: '${selectedDate?.year}/${selectedDate?.month}/${selectedDate?.day} ',
style: const TextStyle(
fontSize: 16, fontWeight: FontWeight.w500),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: SizedBox(
width: 88.0,
height: 25.0,
child: MaterialButton(
onPressed: showDatePicker,
shape: const StadiumBorder(),
color: Colors.blue,
child: const Text(
'select',
style: TextStyle(color: Colors.white, fontSize: 12),
),
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Row(
children: <Widget>[
const Icon(
Icons.brightness_1,
color: Colors.black,
size: 10,
),
const Padding(
padding: EdgeInsets.only(left: 15.0),
child: Text(
"Are you agree",
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
),
const Padding(
padding: EdgeInsets.only(left: 30),
child: Text(
'yes',
style:
TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
),
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
side: MaterialStateBorderSide.resolveWith(
(states) =>
BorderSide(width: 3.0, color: Colors.blueAccent),
),
value: isChecked,
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
),
],
),
),
Padding(
padding: const EdgeInsets.only(bottom: 0.0, top: 150),
child: SizedBox(
width: 160.0,
height: 35.0,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(
color: Colors.blueAccent,
),
),
),
),
onPressed: () {
//do null check 1st
_saveData(dropdownValueMembers!);
_saveDataNumbers(dropdownValueNumber!);
_saveDataBirthday(dropdownValueBirthday!);
_saveDataAgree(isChecked!);
},
child: const Text('next')),
),
),
],
),
),
);
}
}
How to solve and how to add sharedPreference to this datepicker and to checkbox
Lot's of ways to go about it. Simplist way in your case, get rid of all the setStates in all your methods except the last one. You're layering all those setStates and they're calling while other things are still awaiting.
I suggest awaiting each method before calling any setState. You can't await in the initState, but in the first method, call the each of the subsequent ones with awaits from there. So just call checkValueMembers(); (or create a new one getAllValues or whatever).
Within getAllValues, await all the other methods.
Then you can be sure that everything is done, and finally, call setState this way:
WidgetsBinding.instance.addPostFrameCallback((_) {
setState((){});
});
It ensures you don't call setState until the entire widget tree is done.
Entire thing could look like this: remember to get rid of all the other setStates
Future checkValueMembers() async {
await _getData();
await _getDataNumber();
await _getDataBirthday();
await _getDataAgree();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState((){});
});
}

Tried to add shared Preference for two dropdown values but shows then error "Failed assertion: " on Flutter?

this is my output but when I add shared preference then shows an error as I mention below.
I used shared preference dependency in my project. At the initially open app 1st dropdown value must be 'howmany' and 2nd dropdown value 'which' but when selecting any other value and click the next button and closing the application from mobile recents and the user when reopening again then should display the value selected values by the user.
Ex:- At the initially user open app then 1st dropdown value must be 'howmany' , 2nd 'which' and he select 1st dropdown "three" , 2nd dropdown "4th" and click next button after close the app and remove from recents apps. Later when he reopen the app must display dropdown value is "three" and "4th"
like this
In my code shared preferences works prefcetly for when I use only one drop down but when I used two or more dropdowns then shows this error.
error
My code
class _FamilyDetailsScreenState extends State<FamilyDetailsScreen> {
// dropdown buttons
String dropdownValueMembers = 'howmany';
// List of items in our dropdown menu
var items = ['howmany', 'one', 'two', 'three ', 'four ', '5 or more'];
void initState() {
super.initState();
checkValueMembers();
checkValueNumber();
}
//IF "dropdownValueMembers" is empty pass "howmany" word as a initial value if al ready selected then pass the shared preference value
checkValueMembers() {
_getData();
}
_saveData(String dropdownValueMembersShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data", dropdownValueMembersShared);
}
_getData() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueMembers = sharedPreferences.getString("data") ?? "howmany";
setState(() {});
}
// data which child
String dropdownValueNumber = 'which';
// // List of items in our dropdown menu
var number = ['which', '1 st', '2 nd', '3 rd ', '4 th ', '5 th'];
//IF "dropdownValueMembers" is empty pass "which" word as a initial value if al ready selected then pass the shared preference value
checkValueNumber() {
_getDataNumber();
}
_saveDataNumbers(String dropdownValueNumberShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data2", dropdownValueNumberShared);
}
_getDataNumber() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueMembers = sharedPreferences.getString("data2") ?? "which";
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
const Text(
'family details',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.00,
fontWeight: FontWeight.w700,
),
),
const SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 15),
child: Row(
children: <Widget>[
const Icon(
Icons.brightness_1,
color: Colors.black,
size: 10.0,
),
const Padding(
padding: EdgeInsets.only(left: 13),
child: Text(
"Number of children",
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w600),
),
),
Padding(
padding: const EdgeInsets.only(left: 2),
child: Container(
height: 25,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueMembers,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: items.map((String items) {
return DropdownMenuItem(
value: items,
child: SizedBox(
height: 15,
width: 120.0, // for example
child: Text(items,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newValue) {
setState(
() {
dropdownValueMembers = newValue!;
},
);
},
),
),
),
],
),
),
const SizedBox(
height: 25,
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text('Which child'),
),
Padding(
padding:
const EdgeInsets.only(left: 100, right: 0, top: 20),
child: Container(
height: 30,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueNumber,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: number.map((String number) {
return DropdownMenuItem(
value: number,
child: SizedBox(
height: 17,
width: 120.0, // for example
child: Text(number,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newNumber) {
setState(
() {
dropdownValueNumber = newNumber!;
},
);
},
),
),
),
],
),
const SizedBox(
height: 60,
),
Padding(
padding: const EdgeInsets.only(bottom: 0.0, top: 150),
child: SizedBox(
width: 160.0,
height: 35.0,
child: ElevatedButton(
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(
color: Colors.blueAccent,
),
),
),
),
onPressed: () {
_saveData(dropdownValueMembers);
_saveDataNumbers(dropdownValueNumber);
},
child: const Text('next')),
),
),
],
),
),
),
);
}
}
How solve this and save 2 or more data using shared preferences?
The issue coming from
checkValueNumber() {
_getDataNumber();
}
And
_getDataNumber() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueMembers = sharedPreferences.getString("data2") ?? "which"; //this
setState(() {});
}
which is been used on second dropdown and dropdownValueMembers as 1st dropdown value. So the it will be
dropdownValueNumber = sharedPreferences.getString("data2") ?? number.first;
There are some other modification here
class FamilyDetailsScreen extends StatefulWidget {
const FamilyDetailsScreen({super.key});
#override
State<FamilyDetailsScreen> createState() => _FamilyDetailsScreenState();
}
class _FamilyDetailsScreenState extends State<FamilyDetailsScreen> {
// 1st dropdown button
String? dropdownValueMembers;
// List of items in our dropdown menu
List<String> items = [
'howmany',
'one',
'two',
'three ',
'four',
'5 or more'
];
// data which child
String? dropdownValueNumber;
// // List of items in our dropdown menu
List<String> number = ['which', '1 st', '2 nd', '3 rd ', '4 th ', '5 th'];
#override
void initState() {
super.initState();
dropdownValueMembers = items.first;
dropdownValueNumber = number.first;
checkValueMembers();
checkValueNumber();
}
checkValueMembers() {
_getData();
}
_saveData(String dropdownValueMembersShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data", dropdownValueMembersShared);
}
_getData() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueMembers = sharedPreferences.getString("data") ?? items.first;
setState(() {});
}
// 2nd dropdown button
//IF "dropdownValueMembers" is empty pass "which" word as a initial value if al ready selected then pass the shared preference value
checkValueNumber() {
_getDataNumber();
}
_saveDataNumbers(String dropdownValueNumberShared) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("data2", dropdownValueNumberShared);
}
_getDataNumber() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
dropdownValueNumber = sharedPreferences.getString("data2") ?? number.first;
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
const Text(
'family details',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.00,
fontWeight: FontWeight.w700,
),
),
const SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 15),
child: Row(
children: <Widget>[
const Icon(
Icons.brightness_1,
color: Colors.black,
size: 10.0,
),
const Padding(
padding: EdgeInsets.only(left: 13),
child: Text(
"Number of children",
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w600),
),
),
Padding(
padding: const EdgeInsets.only(left: 2),
child: Container(
height: 25,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueMembers,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: items.map((String data) {
return DropdownMenuItem(
value: data,
child: SizedBox(
height: 15,
width: 120.0, // for example
child: Text(data,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newValue) {
setState(
() {
dropdownValueMembers = newValue!;
},
);
},
),
),
),
],
),
),
const SizedBox(
height: 25,
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text('Which child'),
),
Padding(
padding:
const EdgeInsets.only(left: 100, right: 0, top: 20),
child: Container(
height: 30,
decoration: BoxDecoration(
boxShadow: const <BoxShadow>[
//apply shadow on Dropdown button
BoxShadow(
color: Color.fromRGBO(
0, 0, 0, 0.37), //shadow for button
blurRadius: 5) //blur radius of shadow
],
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: DropdownButton(
underline: Container(),
borderRadius: BorderRadius.circular(20),
// Initial Value
value: dropdownValueNumber,
// Down Arrow Icon
icon: const Icon(Icons.keyboard_arrow_down),
// Array list of items
items: number.map((String number) {
return DropdownMenuItem(
value: number,
child: SizedBox(
height: 17,
width: 120.0, // for example
child: Text(number,
style: const TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newNumber) {
setState(
() {
dropdownValueNumber = newNumber!;
},
);
},
),
),
),
],
),
const SizedBox(
height: 60,
),
Padding(
padding: const EdgeInsets.only(bottom: 0.0, top: 150),
child: SizedBox(
width: 160.0,
height: 35.0,
child: ElevatedButton(
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(
color: Colors.blueAccent,
),
),
),
),
onPressed: () {
//do null check 1st
_saveData(dropdownValueMembers!);
_saveDataNumbers(dropdownValueNumber!);
},
child: const Text('next')),
),
),
],
),
),
),
);
}
}

how to make a countdown clock run in the background

I am try to create a timer app which have multiple countdown timer for different task. Issue I am facing is that if I start one timer, and press back button, timer stops. So I want, that timer to run till either it is being paused or timer ends and alerts the user or app is destroyed. how can I do this using Flutter?
import 'package:flutter/material.dart';
import 'package:slide_countdown_clock/slide_countdown_clock.dart';
class TaskCard extends StatefulWidget {
final String label;
final String info;
final String buttonText;
TaskCard({this.buttonText, this.info, this.label});
#override
State<TaskCard> createState() => _TaskCardState();
}
class _TaskCardState extends State<TaskCard> {
bool buttonText = true;
bool buttonPressed = false;
buttonTask() {
if (buttonText == false) {
return RawMaterialButton(
onPressed: () {},
child: Padding(
padding: const EdgeInsets.all(10.0),
child: SlideCountdownClock(
duration: Duration(
minutes: 2,
),
slideDirection: SlideDirection.Up,
separator: ":",
textStyle: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
onDone: () {
setState(() {
buttonText = true;
});
},
),
),
);
} else if (buttonText == true) {
return MaterialButton(
onPressed: () {
setState(() {
buttonText = false;
});
},
child: Text(
'Get Reward',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0),
),
);
}
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.pink[100]),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.pink[100],
offset: Offset(-2, -1),
blurRadius: 5),
],
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.label,
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(widget.info,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 25,
)),
),
Padding(
padding: const EdgeInsets.fromLTRB(90, 0, 90, 0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.pinkAccent,
child: buttonTask()),
),
],
),
)),
);
}
}
You need a separate singleton(initializes at the start) or global(simpler) object to handle your timer. I assume you are declaring your timers in the widgets which is not a very good place for the stuff that you want to retain the state.