Related
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;
}
},
);
How to access context and setstate outside build method in Flutter?
To make the app responsive I need context.
I get error "Undefined name 'context'.
Try correcting the name to one that is defined, or defining the name."
When I write context here:-
class Portfolio extends StatefulWidget {
final BuildContext context1;
const Portfolio({
required this.context1,
Key? key,
}) : super(key: key);
#override
State<Portfolio> createState() => _PortfolioState();
}
DragAndDropList buildList(CardsList list) => DragAndDropList(
header: Padding(
padding: EdgeInsets.only(
left: 15.0,
top: 10,
bottom: 10,
right: 15,
),
child: Row(
children: [
Text(
list.header,
style: TextStyle(
color: Color(0xFF100F32),
fontWeight: FontWeight.w700,
fontSize: responsiveWidth(14, context),
),
),
Spacer(),
Icon(
Icons.more_horiz,
color: Color(0xFF364766),
size: 20,
),
],
),
),
children: list.cards
.map(
(item) => DragAndDropItem(
child: Center(
child: Padding(
padding: EdgeInsets.only(top: 8.0),
child: Container(
width: 280,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
padding: EdgeInsets.all(10),
child: Text(item.text),
),
),
),
),
)
.toList(),
footer: Padding(
padding: EdgeInsets.only(left: 10.0, bottom: 10),
child: addCard == false
? OPopupTrigger(
triggerWidget: Row(
children: [
Icon(
Icons.add,
color: Color(0xFF80899D),
),
Text(
'Add a card',
style: TextStyle(
color: Color(0xFF80899D),
fontSize: 12,
),
),
],
),
barrierDismissible: true,
popupHeader: SizedBox(),
popupContent: Container(
height: 100,
width: 100,
color: Colors.red,
child: Row(
children: [
Text('Hehehe'),
Spacer(),
GestureDetector(
onTap: () {},
child: Icon(Icons.cancel),
),
],
),
),
)
: Column(
children: [
Container(
width: 280,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
padding: EdgeInsets.only(left: 10, top: 10, bottom: 25),
child: TextField(
onChanged: (newText) {
list.textField = newText;
},
maxLines: null,
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
hintText: 'Enter a title for this card...',
hintStyle: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
labelStyle: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
),
),
style: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
),
),
SizedBox(
height: 20,
),
Row(
children: [
GestureDetector(
onTap: () {
list.cards.add(
Cards(text: list.textField, position: 1),
);
print(list.textField);
},
child: Container(
decoration: BoxDecoration(
color: Color(0xFF026AA7),
borderRadius: BorderRadius.circular(5),
),
height: 30,
width: 80,
child: Center(
child: Text(
'Add card',
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
),
),
),
GestureDetector(
onTap: () {
addCard = false;
},
child: Icon(
Icons.close,
color: Color(0xFF80899D),
size: 24,
),
),
],
),
],
),
),
);
class _PortfolioState extends State<Portfolio> {
#override
void initState() {
// TODO: implement initState
lists = widgets.map(buildList).toList();
}
late List<DragAndDropList> lists;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Stack(
Full code file:-
import 'package:expandable_reorderable_list/expandable_reorderable_list.dart';
import 'package:flutter/material.dart';
import 'package:o_popup/o_popup.dart';
import 'package:project_submission/responsive.dart';
import 'drag_and_drop_list.dart';
void main() {
runApp(const MyApp());
}
class CardsList {
final String header;
final List<Cards> cards;
String textField;
CardsList({
required this.header,
required this.cards,
this.textField = '',
});
}
class Cards {
final String text;
final int position;
const Cards({
required this.text,
required this.position,
});
}
List<CardsList> widgets = [
CardsList(
header: 'To-do',
textField: '',
cards: [
Cards(
text:
'Trello Tip: Card labels! What do they mean? (Click for more info)',
position: 1),
Cards(text: 'Project "Teamwork Dream Work" Launch Timeline', position: 2),
Cards(text: 'Stakeholders', position: 3),
],
),
CardsList(
header: 'header2',
textField: '',
cards: [
Cards(
text:
'Trello Tip: Card labels! What do they mean? (Click for more info)',
position: 1),
Cards(text: 'Project "Teamwork Dream Work" Launch Timeline', position: 2),
Cards(text: 'Stakeholders', position: 3),
],
),
CardsList(
header: 'header3',
textField: '',
cards: [
Cards(
text:
'Trello Tip: Card labels! What do they mean? (Click for more info)',
position: 1),
Cards(text: 'Project "Teamwork Dream Work" Launch Timeline', position: 2),
Cards(text: 'Stakeholders', position: 3),
],
),
CardsList(
header: 'header4',
textField: '',
cards: [
Cards(text: 'Hello1', position: 1),
Cards(text: 'Hello2', position: 2),
Cards(text: 'Hello3', position: 3),
],
),
];
bool addCard = false;
bool greyArea = false;
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: Wait());
}
}
class Wait extends StatefulWidget {
const Wait({Key? key}) : super(key: key);
#override
State<Wait> createState() => _WaitState();
}
class _WaitState extends State<Wait> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Portfolio(
context1: context,
)));
},
child: Text('Wait'),
);
}
}
class Portfolio extends StatefulWidget {
final BuildContext context1;
const Portfolio({
required this.context1,
Key? key,
}) : super(key: key);
#override
State<Portfolio> createState() => _PortfolioState();
}
DragAndDropList buildList(CardsList list) => DragAndDropList(
header: Padding(
padding: EdgeInsets.only(
left: 15.0,
top: 10,
bottom: 10,
right: 15,
),
child: Row(
children: [
Text(
list.header,
style: TextStyle(
color: Color(0xFF100F32),
fontWeight: FontWeight.w700,
fontSize: responsiveWidth(14, context),
),
),
Spacer(),
Icon(
Icons.more_horiz,
color: Color(0xFF364766),
size: 20,
),
],
),
),
children: list.cards
.map(
(item) => DragAndDropItem(
child: Center(
child: Padding(
padding: EdgeInsets.only(top: 8.0),
child: Container(
width: 280,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
padding: EdgeInsets.all(10),
child: Text(item.text),
),
),
),
),
)
.toList(),
footer: Padding(
padding: EdgeInsets.only(left: 10.0, bottom: 10),
child: addCard == false
? OPopupTrigger(
triggerWidget: Row(
children: [
Icon(
Icons.add,
color: Color(0xFF80899D),
),
Text(
'Add a card',
style: TextStyle(
color: Color(0xFF80899D),
fontSize: 12,
),
),
],
),
barrierDismissible: true,
popupHeader: SizedBox(),
popupContent: Container(
height: 100,
width: 100,
color: Colors.red,
child: Row(
children: [
Text('Hehehe'),
Spacer(),
GestureDetector(
onTap: () {},
child: Icon(Icons.cancel),
),
],
),
),
)
: Column(
children: [
Container(
width: 280,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
padding: EdgeInsets.only(left: 10, top: 10, bottom: 25),
child: TextField(
onChanged: (newText) {
list.textField = newText;
},
maxLines: null,
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
hintText: 'Enter a title for this card...',
hintStyle: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
labelStyle: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
),
),
style: TextStyle(
color: Color(0xFF838EA0),
fontSize: 12,
),
),
),
SizedBox(
height: 20,
),
Row(
children: [
GestureDetector(
onTap: () {
list.cards.add(
Cards(text: list.textField, position: 1),
);
print(list.textField);
},
child: Container(
decoration: BoxDecoration(
color: Color(0xFF026AA7),
borderRadius: BorderRadius.circular(5),
),
height: 30,
width: 80,
child: Center(
child: Text(
'Add card',
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
),
),
),
GestureDetector(
onTap: () {
addCard = false;
},
child: Icon(
Icons.close,
color: Color(0xFF80899D),
size: 24,
),
),
],
),
],
),
),
);
class _PortfolioState extends State<Portfolio> {
#override
void initState() {
// TODO: implement initState
lists = widgets.map(buildList).toList();
}
late List<DragAndDropList> lists;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF2B1B81),
Color(0xFFDD499D),
],
),
),
),
Text(
'Project Management',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 20,
),
),
Padding(
padding: EdgeInsets.only(
left: 10,
top: 30,
),
child: DragAndDropLists(
listWidth: 300,
axis: Axis.horizontal,
listPadding: EdgeInsets.only(right: 10),
itemDragOnLongPress: false,
children: lists,
onItemReorder: onItemReorder,
onListReorder: onListReorder,
),
),
// Row(
// children: [
// DragTarget(
// onAccept: (data) {
// setState(() {
// widgets.add(data);
// widgets.remove(data);
// });
// },
// onWillAccept: (data) {
// setState(() {
// greyArea = true;
// });
// return true;
// },
// onLeave: (data) {
// setState(() {
// greyArea = false;
// widgets
// .sort((a, b) => a['position'].compareTo(b['price']));
// });
// },
// builder: (context, _, __) => SizedBox(
// height: MediaQuery.of(context).size.height,
// child: Column(
// children: [
// Padding(
// padding: EdgeInsets.only(left: 30.0, top: 30),
// child: Container(
// width: 300,
// decoration: BoxDecoration(
// color: Color(0xFFEBECF0),
// borderRadius: BorderRadius.circular(6),
// ),
// child: Column(
// children: [
// Text(
// 'Project Resources',
// style: TextStyle(
// color: Color(0xFF5D6C83),
// fontWeight: FontWeight.w600,
// fontSize: 12),
// ),
// for (var wid in widgets)
// Column(
// children: [
// Padding(
// padding: EdgeInsets.all(8.0),
// child: Draggable(
// child: Container(
// decoration: BoxDecoration(
// color: Colors.green,
// ),
// child: Text(wid['text']),
// height: 100,
// width: 100,
// ),
// data: wid,
// feedback: Container(
// color: Colors.red,
// height: 100,
// width: 100,
// ),
// childWhenDragging: SizedBox(),
// ),
// ),
// DragTarget(
// onAccept: (data) {
// setState(() {
// widgets.add({
// 'text': data['text'],
// 'position': 1
// });
// widgets.remove({
// 'text': data['text'],
// 'position': data['position']
// });
// });
// },
// onWillAccept: (data) {
// setState(() {
// greyArea = true;
// });
// return true;
// },
// onLeave: (data) {
// setState(() {
// greyArea = false;
// });
// },
// builder: (context, _, __) {
// print(_);
// return SizedBox();
// },
// ),
// ],
// ),
// greyArea == true
// ? Container(
// color: Colors.grey,
// height: 20,
// width: 100,
// )
// : SizedBox(),
// SizedBox(
// height: 8,
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
],
),
),
);
}
void onItemReorder(
int oldItemIndex,
int oldListIndex,
int newItemIndex,
int newListIndex,
) {
setState(() {
final oldListItems = lists[oldListIndex].children;
final newListItems = lists[newListIndex].children;
final movedItem = oldListItems.removeAt(oldItemIndex);
newListItems.insert(newItemIndex, movedItem);
});
print(lists);
}
void onListReorder(
int oldListIndex,
int newListIndex,
) {
setState(() {
final movedList = lists.removeAt(oldListIndex);
lists.insert(newListIndex, movedList);
});
}
}
I'm trying to save a position of indicator slider image, when I change to another page, the position of image works, but the indicator is not. I use PageStorage key to save the position. This is where I place a list of slider image:
body: PageStorage(
bucket: bucketGlobal,
child: ListView.builder(
itemBuilder: (context, index) {
return ItemFeed(
userModel: DataDefault.userModelDemo,
index: index,
);
},
itemCount: DataDefault.userModelDemo.length,
key: PageStorageKey<String>('listFeed'),
shrinkWrap: true,
padding: EdgeInsets.all(5),
scrollDirection: Axis.vertical,
),
),
);
And this is the code for its item:
Widget buildFeedItem(List userModel, int index, String text) {
return Column(
children: [
//header
Row(
children: [
CircleAvatar(
backgroundImage: AssetImage(
userModel[index]['userAvaUrl'],
),
),
SizedBox(
width: 5,
),
Text(
userModel[index]['userName'],
),
],
),
SizedBox(
height: 15,
),
//image post
GestureDetector(
onDoubleTap: () {
setState(() {
isLikeAnimating = true;
isHeartAnimating = true;
});
},
child: Stack(
alignment: Alignment.center,
children: [
// list postUrl
SliderImage(
onPageChange: (index, reason) {
setState(() {
currentIndex = index;
});
},
controller: sliderController,
key: PageStorageKey<String>('listFeed'),
listPost: userModel[index]['postUrl'],
),
Positioned(
top: 0,
right: 10,
child: Container(
margin: EdgeInsets.only(
top: 10,
),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: blackColor.withOpacity(0.6),
borderRadius: BorderRadius.circular(20),
),
child: Text(
(currentIndex + 1).toString() +
'/' +
userModel[index]['postUrl'].length.toString(),
key: PageStorageKey<String>('listFeed'),
style: TextStyle(
color: primaryColor,
),
),
),
),
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isLikeAnimating ? 1 : 0,
child: LikeAnimation(
isAnimating: isLikeAnimating,
child: Icon(
Icons.favorite,
color: isHeartAnimating ? errorColor : primaryColor,
size: 100,
),
duration: const Duration(
milliseconds: 400,
),
onEnd: () {
setState(() {
isLikeAnimating = false;
});
},
),
),
],
),
),
SizedBox(
height: 10,
),
Container(
// color: blueColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//icon like
CustomIcon(
child: Icon(
isHeartAnimating
? Icons.favorite_rounded
: Icons.favorite_border,
color: isHeartAnimating ? errorColor : blackColor,
size: 30,
),
onPress: () {
setState(() {
isLikeAnimating = true;
isHeartAnimating = !isHeartAnimating;
});
},
isAnimating: isLikeAnimating,
onEnd: () {
setState(
() {
isLikeAnimating = false;
},
);
},
),
SizedBox(
width: 10,
),
//icon comment
CustomIcon(
child: Icon(
Icons.chat_bubble_outline,
color: blackColor,
size: 30,
),
onPress: () {
setState(() {
isCommentAnimating = true;
});
},
isAnimating: isCommentAnimating,
onEnd: () {
setState(
() {
isCommentAnimating = false;
},
);
},
),
SizedBox(
width: 10,
),
//icon share
CustomIcon(
child: Icon(
Icons.send,
color: blackColor,
size: 30,
),
onPress: () {
setState(() {
isShareAnimating = true;
});
},
isAnimating: isShareAnimating,
onEnd: () {
setState(
() {
isShareAnimating = false;
},
);
},
),
Spacer(),
Align(
alignment: Alignment.center,
child: AnimatedSmoothIndicator(
activeIndex: currentIndex,
count: userModel[index]['postUrl'].length,
effect: WormEffect(
activeDotColor: blueColor,
dotColor: secondaryColor.withOpacity(0.4),
dotHeight: 5,
dotWidth: 5,
spacing: 2.0,
),
),
),
Spacer(),
],
),
),
],
);
}
#override
Widget build(BuildContext context) {
return Container(
key: PageStorageKey<String>('listFeed'),
child: buildFeedItem(
widget.userModel,
widget.index,
'CC',
),
);
}
Why does the slider image work but the indicator is not?
How can I fix it? Please help
I have this error:
The following FileSystemException was thrown resolving an image codec:
Cannot open file, path = '/Users/todo/Library/Developer/CoreSimulator/Devices/82205CEC-3D83-4A29-BF17-01C5B0515F71/data/Containers/Data/Application/035B9913-BEC5-46BA-84A5-8C1FE3C4E671/tmp/image_picker_B8D488A3-2790-4D53-A5D8-52E57E2C4108-76094-000003172DF085D2.jpg' (OS Error: No such file or directory, errno = 2)
When the exception was thrown, this was the stack
only when use iphone simulator while android emulator no problem
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../app/utility.dart';
import '../db/aql_db.dart';
import '../globals.dart';
import '../menu_page.dart';
import '../model/aql_model.dart';
import '../widget/input_text.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
var _current = resultsFld[0];
class AqlPg extends StatefulWidget {
const AqlPg({Key? key}) : super(key: key);
#override
State<AqlPg> createState() => _AqlPgState();
}
class _AqlPgState extends State<AqlPg> {
final List<TextEditingController> _criticalController = [];
final List<TextEditingController> _majorController = [];
final List<TextEditingController> _minorController = [];
final List<TextEditingController> _imgCommintControllers = [];
final _irController = TextEditingController();
bool clickedCentreFAB =
false; //boolean used to handle container animation which expands from the FAB
int selectedIndex =
0; //to handle which item is currently selected in the bottom app bar
//call this method on click of each bottom app bar item to update the screen
void updateTabSelection(int index, String buttonText) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
//
_irController.text = aqltbl.ir ?? '';
String _current = aqltbl.result ?? resultsFld[0];
//
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
//---- stack for FloatingActionButton
Stack(
children: <Widget>[
//this is the code for the widget container that comes from behind the floating action button (FAB)
Align(
alignment: FractionalOffset.bottomCenter,
child: AnimatedContainer(
child: const Text(
'Hello',
style: TextStyle(fontSize: 18, color: whiteColor),
),
duration: const Duration(milliseconds: 250),
//if clickedCentreFAB == true, the first parameter is used. If it's false, the second.
height: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
width: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
clickedCentreFAB ? 0.0 : 300.0),
color: Colors.blue),
),
),
],
),
// --- Top Page Title
const SizedBox(
height: 50,
),
const Center(
child: Text(
'Aql page',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: medBlueColor),
),
),
Text(
'Shipment no:$shipmentId',
style: const TextStyle(color: medBlueColor),
),
//--- input container
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
height: 270,
width: 300,
margin: const EdgeInsets.only(top: 5),
child: ListView.builder(
itemCount: (aqltbl.aql ?? []).length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
//here
var _aqlList = aqltbl.aql![index];
//
if (aqltbl.aql!.length > _criticalController.length) {
_criticalController.add(TextEditingController());
_majorController.add(TextEditingController());
_minorController.add(TextEditingController());
}
//
_criticalController[index].text =
_aqlList.critical ?? '';
_majorController[index].text = _aqlList.major ?? '';
_minorController[index].text = _aqlList.minor ?? '';
//
return Column(
children: [
Container(
height: 260,
width: 200,
margin: const EdgeInsets.only(left: 10),
padding: const EdgeInsets.all(10),
// ignore: prefer_const_constructors
decoration: BoxDecoration(
color: lightBlue,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Text(
(_aqlList.name ?? '').toString(),
style: const TextStyle(
color: medBlueColor,
fontSize: 13,
),
),
// ignore: prefer_const_constructors
MyInputField(
title: 'critical',
hint: 'write critical ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _criticalController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].critical = value;
_save();
});
},
),
MyInputField(
title: 'majority',
hint: 'write majority ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _majorController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].major = value;
_save();
});
},
),
MyInputField(
title: 'minority',
hint: 'write minority ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _minorController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].minor = value;
_save();
});
},
),
],
),
),
],
);
}),
),
Container(
height: 270,
width: 300,
margin: const EdgeInsets.only(right: 10, left: 20),
padding: const EdgeInsets.only(
left: 10, bottom: 3, right: 10, top: 5),
decoration: const BoxDecoration(
color: lightBlue,
),
child: Column(
children: [
const Text(
'Summery results',
style: TextStyle(color: medBlueColor),
),
Container(
margin: const EdgeInsets.only(top: 10, bottom: 5),
alignment: Alignment.centerLeft,
child: const Text(
'Results',
style: TextStyle(color: medBlueColor),
),
),
Container(
padding: const EdgeInsets.only(right: 5, left: 5),
decoration: BoxDecoration(
color: whiteColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: borderColor,
)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: whiteColor,
value: aqltbl.result,
hint: const Text('select result'),
isExpanded: true,
iconSize: 36,
icon: const Icon(Icons.arrow_drop_down),
items: resultsFld.map((res) {
return DropdownMenuItem<String>(
value: res,
child: Text(
res,
style: const TextStyle(
fontFamily: 'tajawal',
fontSize: 15,
color: medBlueColor),
),
);
}).toList(),
onChanged: (val) {
setState(() {
aqltbl.result = val;
});
_save();
},
),
),
),
// aqltbl.result = selRes;
MyInputField(
width: 300,
title: 'information remarks (ir)',
hint: '',
maxLines: 3,
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _irController,
onSubmit: (value) {
aqltbl.ir = value;
_save();
},
),
],
),
),
],
),
),
//Images Container
Container(
height: 400,
padding: const EdgeInsets.all(0),
margin: const EdgeInsets.only(bottom: 10, left: 10),
decoration: const BoxDecoration(color: lightGrey),
child: (aqltbl.images ?? []).isEmpty
? Column(
children: [
Image.asset(
'images/empty-photo.jpg',
height: 300,
),
Container(
margin: const EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Click'),
Text(
'Camera button',
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(' to add new photo'),
],
)),
],
)
: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: (aqltbl.images ?? []).length,
itemBuilder: (context, imgIndex) {
String? _image =
(aqltbl.images ?? [])[imgIndex].name.toString();
inspect('aql image file');
File(_image).exists() == true
? inspect('image exist')
: inspect('not exist: ' + _image);
inspect('_image: ' + _image);
if (aqltbl.images!.length >
_imgCommintControllers.length) {
_imgCommintControllers.add(TextEditingController());
}
_imgCommintControllers[imgIndex].text =
aqltbl.images![imgIndex].imgComment!;
inspect(_imgCommintControllers.length);
return Container(
margin: const EdgeInsets.only(left: 5),
height: 300,
child: Column(
children: [
Stack(
children: [
Image.file(
File(_image),
height: 300,
),
Container(
decoration: const BoxDecoration(
color: medBlueColor,
),
child: IconButton(
onPressed: () {
inspect('clear');
String imgName =
aqltbl.images![imgIndex].name ??
'';
aqltbl.images!.removeAt(imgIndex);
// aqltbl.images!.removeWhere(
// (item) => item.name == imgName);
_imgCommintControllers
.removeAt(imgIndex);
setState(() {});
},
color: whiteColor,
icon: const Icon(Icons.clear)),
)
],
),
MyInputField(
title: 'Write remarks about image',
hint: '',
controller: _imgCommintControllers[imgIndex],
onSubmit: (value) {
aqltbl.images![imgIndex].imgComment = value;
aqltbl.images![imgIndex].name = _image;
_save();
},
),
],
));
}),
),
],
),
),
// --- FloatingActionButton
floatingActionButtonLocation: FloatingActionButtonLocation
.centerDocked, //specify the location of the FAB
floatingActionButton: FloatingActionButton(
backgroundColor: medBlueColor,
onPressed: () {
inspect(aqltbl);
setState(() {
clickedCentreFAB =
!clickedCentreFAB; //to update the animated container
});
},
tooltip: "Centre FAB",
child: Container(
margin: const EdgeInsets.all(15.0),
child: const Icon(Icons.send),
),
elevation: 4.0,
),
// --- bottom action bar
bottomNavigationBar: BottomAppBar(
child: Container(
margin: const EdgeInsets.only(left: 12.0, right: 12.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
//to leave space in between the bottom app bar items and below the FAB
IconButton(
//update the bottom app bar view each time an item is clicked
onPressed: () {
// updateTabSelection(0, "Home");
Get.to(const MainMenu());
},
iconSize: 27.0,
icon: Image.asset(
'images/logo.png',
color: medBlueColor,
),
),
const SizedBox(
width: 50.0,
),
IconButton(
onPressed: () async {
// updateTabSelection(2, "Incoming");
await _takeImage('gallery');
},
iconSize: 27.0,
icon: const Icon(
Icons.image_outlined,
color: medBlueColor,
),
),
IconButton(
onPressed: () async {
// updateTabSelection(1, "Outgoing");
await _takeImage('camera');
},
iconSize: 27.0,
icon: const Icon(
Icons.camera_alt,
color: medBlueColor,
),
),
],
),
),
//to add a space between the FAB and BottomAppBar
shape: const CircularNotchedRectangle(),
//color of the BottomAppBar
color: Colors.white,
),
);
}
_save() {
inspect('submit');
saveAql(shipmentId, aqltbl);
box.write('aql'+shipmentId.toString(), aqltbl);
}
_takeImage(method) async {
String _imgPath = await imageFromDevice(method);
if (_imgPath != empty) {
ImagesModel imgMdl = ImagesModel();
imgMdl.name = _imgPath;
imgMdl.imgComment = '';
if (aqltbl.images != null) {
// _saveLocaly(close: 0);
setState(() {
aqltbl.images!.add(imgMdl);
_save();
});
}
}
}
Future _sendAqlToServer() async {
try {
var response = await http.post(urlSendProductPhoto, body: {
'aql': json.encode(aqltbl).toString(),
'id': shipmentId.toString(),
});
if (response.statusCode == 200) {
Get.snackbar('Success', 'Image successfully uploaded');
return response.body;
} else {
Get.snackbar('Fail', 'Image not uploaded');
inspect('Request failed with status: ${response.statusCode}.');
return 'empty';
}
} catch (socketException) {
Get.snackbar('warning', 'Image not uploaded');
return 'empty';
}
}
}
Try following the path that it is saying it cannot find in your computer, I had a similar issue, I tried opening an Iphone 12 instead of an Iphone 13 and it worked out the issue, my problem was I inadvertently deleted a few files I shouldn't have.
I have a Column with some widgets. Inside the Column are some TextFields. When the textfields receive and lose focus I want to hide a widget. I think when calling SetState it is not redrawing the conditional below.
AutoCompleteTextField:
child: AutoCompleteTextView(
suggestionsApiFetchDelay: 300,
focusGained: () {
_pauseStream(
stream: Streams.dropoff);
_startStream(
stream: Streams.pickup);
setState(() {
_showCurrentLocalTile = true;
});
},
focusLost: () {
setState(() {
_showCurrentLocalTile = false;
});
_pauseStream(
stream: Streams.dropoff);
}
)
void _showBottomSheet() {
setState(() {
_showPersBottomSheetCallBack = null;
});
// Be sure to set to get and set current physical address
LocationService().getAddressFromLatLng().then((value) {
if (value != null) {
_currentAddress = value;
}
});
_scaffoldKey.currentState
.showBottomSheet((context) {
return new Container(
height: 400.0,
color: Colors.white,
padding: const EdgeInsets.only(left: 2, right: 2),
child: new Center(
// child: new Text('Persistent Bottom Sheet'),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 125,
child: Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {},
),
],
),
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Container(
alignment: Alignment.topCenter,
height: 35,
margin: const EdgeInsets.only(
top: 40, left: 0, right: 0),
child: AutoCompleteTextView(
suggestionsApiFetchDelay: 300,
focusGained: () {
_pauseStream(
stream: Streams.dropoff);
_startStream(
stream: Streams.pickup);
setState(() {
_showCurrentLocalTile = true;
});
},
onTapCallback: (_) async {
_startStream(
stream: Streams.dropoff);
// locationSavedStatus = LocationSaveStatus.inProgress;
// saveLocationValuesFromGeoCoding(bloc).then(
// (_) =>
// locationSavedStatus = LocationSaveStatus.saved,
// );
},
focusLost: () {
setState(() {
_showCurrentLocalTile = false;
});
_pauseStream(
stream: Streams.dropoff);
// locationSavedStatus = LocationSaveStatus.saved;
// if (startEditingController.text.isEmpty) {
// city = '';
// state = '';
// country = '';
// startEditingController.text = '';
// } else {
// startEditingController.text = getLocationString(
// country: country, state: state, city: city);
// }
},
onValueChanged: (String text) {
// locationSavedStatus = text.isNotEmpty
// ? (getLocationString(
// city: '', state: '', country: '')
// .trim() ==
// text.trim())
// ? LocationSaveStatus.saved
// : LocationSaveStatus.notSaved
// : LocationSaveStatus.saved;
},
controller: startEditingController,
suggestionStyle: Theme.of(context)
.textTheme
.bodyText2,
getSuggestionsMethod:
getLocationSuggestionsList,
tfTextAlign: TextAlign.left,
tfCursorColor: Colors.black,
tfStyle: TextStyle(
fontSize: 16,
color: Theme.of(context)
.textTheme
.bodyText2
.color,
),
tfTextDecoration: InputDecoration(
contentPadding: EdgeInsets.only(
top: 0, left: 8.0),
filled: true,
fillColor: Colors.grey[200],
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1.0),
borderRadius: BorderRadius.zero,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1.0),
borderRadius: BorderRadius.zero,
),
hintText: "",
labelText: 'Start',
labelStyle:
kPurpleLabelStyle,
),
),
),
Container(
height: 35,
margin: const EdgeInsets.only(
top: 5,
left: 0,
right: 0,
bottom: 5),
child: AutoCompleteTextView(
suggestionsApiFetchDelay: 300,
focusGained: () {
setState(() {
_showCurrentLocalTile = true;
});
_pauseStream(
stream: Streams.pickup);
_startStream(
stream: Streams.dropoff);
},
onTapCallback: (_) async {
_startStream(
stream: Streams.pickup);
// locationSavedStatus = LocationSaveStatus.inProgress;
// saveLocationValuesFromGeoCoding(bloc).then(
// (_) =>
// locationSavedStatus = LocationSaveStatus.saved,
// );
},
focusLost: () {
setState(() {
_showCurrentLocalTile = false;
});
_pauseStream(
stream: Streams.pickup);
// locationSavedStatus = LocationSaveStatus.saved;
// if (startEditingController.text.isEmpty) {
// city = '';
// state = '';
// country = '';
// startEditingController.text = '';
// } else {
// startEditingController.text = getLocationString(
// country: country, state: state, city: city);
// }
},
onValueChanged: (String text) {
// locationSavedStatus = text.isNotEmpty
// ? (getLocationString(
// city: '', state: '', country: '')
// .trim() ==
// text.trim())
// ? LocationSaveStatus.saved
// : LocationSaveStatus.notSaved
// : LocationSaveStatus.saved;
},
controller:
destinationEditingController,
suggestionStyle: Theme.of(context)
.textTheme
.bodyText2,
getSuggestionsMethod:
getLocationSuggestionsList,
tfTextAlign: TextAlign.left,
tfCursorColor: Colors.black,
tfStyle: TextStyle(
fontSize: 16,
color: Theme.of(context)
.textTheme
.bodyText2
.color,
),
tfTextDecoration: InputDecoration(
contentPadding: EdgeInsets.only(
top: 0, left: 8.0),
filled: true,
fillColor: Colors.grey[300],
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1.0),
borderRadius: BorderRadius.zero,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1.0),
borderRadius: BorderRadius.zero,
),
hintText: "",
labelText: 'Destination',
labelStyle:
kPurpleLabelStyle,
),
),
)
]),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Stack(
alignment: Alignment.bottomLeft,
children: [
ButtonTheme(
padding: EdgeInsets.symmetric(
vertical: 4.0,
horizontal:
8.0), //adds padding inside the button
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap, //limits the touch area to the button area
minWidth: 45, //wraps child's width
height: 45, //wraps child's height
child: FlatButton(
color: Colors.white,
textColor: Colors.black,
disabledColor: Colors.grey[100],
disabledTextColor: Colors.white,
padding: EdgeInsets.only(
top: 10,
left: 8,
bottom: 8,
right: 12),
splashColor: Colors.grey[100],
onPressed: () {
/*...*/
},
child: Text(
"Done",
style:
TextStyle(fontSize: 14.0),
),
),
),
// IconButton(
// icon: Icon(Icons.add),
// color: Colors.black,
// onPressed: () {},
// ),
]),
],
),
]),
),
],
),
),
SizedBox(
height: 15.0,
),
_showCurrentLocalTile
? GestureDetector(
onTap: () {
_setPickupAddressToAutoComplete(_currentAddress);
print(_currentAddress);
},
child: Container(
height: 48,
child: Padding(
padding: const EdgeInsets.fromLTRB(
16.0, 8.0, 16.0, 0.0),
child: Row(
children: <Widget>[
Icon(Icons.my_location),
Padding(
padding: EdgeInsets.only(
left: 8.0, top: 0.0, bottom: 0.0),
child: Text("Current Location"),
)
],
),
),
),
)
: SizedBox(
height: 15.0,
),
Container(
height: 200,
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0),
child: StreamBuilder<List<GoogleAddress>>(
stream: pickupStreamController.stream,
builder: (context, snapshot) => snapshot.data != null
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
print('Render $index');
if (snapshot.data != null) {
print("${snapshot.data}");
return _createListItem(
icon: Icons.location_on,
googleplace: snapshot.data[index],
onTap: () {
_setPickupAddressToAutoComplete(
snapshot.data[index].address);
print("${snapshot.data[index]}");
});
} else {}
},
)
: SizedBox(height: 15.0),
),
),
),
],
),
),
);
})
.closed
.whenComplete(() {
if (mounted) {
setState(() {
_showPersBottomSheetCallBack = _showBottomSheet;
});
}
});
}