Being new to Flutter, I have created a ExpansionTile (see below screenshot) and have added EditField as a Child.
Here ExpansioTile and comment EditField is created dynamically based on server response.
Inside each ExpansionTile there will be multiple TextFields
Now how do I add TextFieldController dynamically and get all values upon button click?
ExpansionTile Code
FutureBuilder(
future: _fetchQuestions(),
builder: (context, AsyncSnapshot snapshot){
if (snapshot.hasError) {
return Text('Error ${snapshot.error}');
}
else if (snapshot.hasData) {
return new Padding(
padding: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 0.0),
child: Container(
child: PageView.builder(
physics: new NeverScrollableScrollPhysics(),
controller: _pageController,
itemCount: snapshot.data[0].auditAreas.length,
onPageChanged: (int index) {
print('## on page changed $index');
},
itemBuilder: (BuildContext context, int index) {
print('## index '+index.toString());
List<QuestionGroups> listQuestionsGrp = snapshot.data[0].auditAreas[index].questionGroups;
print('## question grp list size == '+listQuestionsGrp.length.toString());
List<Widget> list = new List<Widget>();
for (int i=0; i<listQuestionsGrp.length; i++){
bloc.newFields();
List<Widget> listItemWidgets = new List<Widget>();
// below list(listAuditQues) is used to get the questions from question groups
List<AuditQuestions> listAuditQues = listQuestionsGrp[i].auditQuestions;
for (int j=0; j<listAuditQues.length; j++){
print('# audit question id == '+listAuditQues[j].auditQuestionId.toString());
// _mapController.map(listAuditQues[j].auditQuestionId, _textController);
// _controllers.add(TextEditingController());
List<AuditQuestionAnswers> listAuditQuestAns = listAuditQues[j].auditQuestionAnswers;
print('## list of question and answers used for radio buttons == '+listAuditQuestAns.length.toString());
List<Widget> listTitleOfRadioButtons = new List<Widget>();
for (int k=0; k<listAuditQuestAns.length; k++){
// here have to get the list of radio button text and append below inside the column
List<AuditQuestionAnswerOptionParameters> listQuesAnsParameter = listAuditQuestAns[k].auditQuestionAnswerOptionParameters;
print('## list question answer list size == '+listQuesAnsParameter.length.toString());
List<Widget> listRadioButtons = new List<Widget>();
for (int m=0; m<listQuesAnsParameter.length; m++){
listRadioButtons.add(
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Radio(value: 0, groupValue: null, onChanged: null, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,),
new Text(listQuesAnsParameter[m].answerOptionParameterTitle,style: TextStyle(
fontSize: 12.0
))
],
)
);
}
listTitleOfRadioButtons.add(
Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Container(
margin: EdgeInsets.fromLTRB(10.0, 4.0, 0.0, 4.0),
child: Text(listAuditQuestAns[k].auditEntityTitle,
style: TextStyle(fontSize: 13.5),),
),
),
Row(
children: listRadioButtons,
)
],
)
);
}
// Here adding expansion item content
listItemWidgets.add(
Column(
children: <Widget>[
Row(
// mainAxisAlignment: message.author == username ? MainAxisAlignment.end : MainAxisAlignment.start,
//this will determine if the message should be displayed left or right
children: [
Flexible(
//Wrapping the container with flexible widget
child: Container(
padding: EdgeInsets.all(6.0),
margin: EdgeInsets.all(4.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
border: Border.all(color: Colors.black)
),
child: Row(
children: <Widget>[
Flexible(
//We only want to wrap the text message with flexible widget
child: Container(
child: Text(
listAuditQues[j].title,
)
)
),
],
)
),
)
]
),
Column(
children: listTitleOfRadioButtons
),
Container(
height: 80,
margin: EdgeInsets.all(4.0),
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 80.0,
),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: SizedBox(
height: 80.0,
child: new TextFormField(
// controller: _controllers[j],
maxLines: 60,
decoration: new InputDecoration(
labelText: "Comment",
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.black, width: 0.8)),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.black, width: 0.8)),
),
),
),
),
),
),
),
new Container(
margin: EdgeInsets.all(4.0),
padding: EdgeInsets.fromLTRB(2.0, 4.0, 0.0, 0.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: (){
print('## index of pager $index');
print('## index of main lopp $i');
print('## index of lopp $j');
},
child: new Icon(Icons.camera_alt,
size: 22.0, color: Colors.black),
),
new Icon(Icons.attach_file,
size: 22.0, color: Colors.black),
new Text("(4)", style: TextStyle(fontSize: 12.0))
],
),
),
Container(
margin: EdgeInsets.all(4.0),
child: Divider(height: 4.0,color: Colors.black),
)
],
)
);
}
// Main Title of expansion list adding here
list.add(customExpansionTile.ExpansionTile(
headerBackgroundColor: Colors.grey,
backgroundColor: Colors.white,
iconColor: Colors.black,
title: Text(listQuestionsGrp[i].title, style: TextStyle(
fontSize: 14.0
)),
children: listItemWidgets
));
}
return new ListView(
children: list,
);
// return _buidlExpnsionListTile(snapshot.data[0]);
/*List<AuditAreas> auditAreaList = snapshot.data[index].auditAreas;
print('## audit area list size == ${auditAreaList.length}');
return Text('Screen index == '+index.toString());*/
},
),
),
);
}
else{
return CircularProgressIndicator();
}
},
)
Please help me out..
Initialize it:
TextEditingController controller;
On initState:
#override
initState() {
super.initState();
controller = new TextEditingController();
}
Controller example in TextFormField:
new TextFormField(
validator: (senha) =>
senha.isEmpty ? 'Por favor insira sua senha' : null,
onSaved: (senha) => _pass = senha,
obscureText: true,
textAlign: TextAlign.start,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.vpn_key,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0)),
filled: true,
hintText: 'Senha',
),
controller: controller,
),
To access the TextFormField text just make controller.text
Related
I'm using flutter_maps map and overlaying a custom search bar with drop down menu. When user searches, locations appear and should be clickable. Using the below code, the UI appears, but clicks aren't possible and nothing happens. I've also noticed the list view can't be scrolled either, can anyone see what the issue is?
List<Widget> _locations = [];
Future<void> searchLocations(String input) async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final locationsDao = database.locationDao;
locationsDao.searchLocations(input).then((value) => {
setState(() {
_locations = [];
value.forEach((element) {
_locations.add(locationItem(element));
});
})
});
}
#override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(51.5072, -0.1276),
zoom: zoom,
interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag,
),
children: [
TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png"),
MarkerLayer(markers: _markers),
Padding(
padding:
const EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
child: SizedBox(
height: 56.0,
child: Card(
shape: roundedCorner32,
elevation: 6.0,
child: Wrap(children: [
Column(children: [
TextField(
cursorColor: Theme.of(context).colorScheme.secondary,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 16.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
)),
filled: true,
hintStyle: TextStyle(color: Colors.grey[800]),
hintText: search,
fillColor: Colors.white),
onChanged: (value) {
searchLocations(value);
},
),
if (_locations.isNotEmpty) ...[
Card(
color: Theme.of(context).colorScheme.primary,
shape: roundedCorner16,
elevation: 6.0,
child: Wrap(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.all(8.0),
color: Theme.of(context).colorScheme.primary,
child: ListView.separated(
shrinkWrap: true,
itemCount: _locations.length,
itemBuilder:
(BuildContext context, int index) {
return GestureDetector(
onTap: () {
print("XXXXXXXXXXX");
},
child: _locations[index],
);
}, separatorBuilder: (BuildContext context, int index) {
return const SizedBox(height: 8.0);
},),
),
),
]),
)
]
]),
]),
),
)),
]);
}
Widget locationItem(Location location) {
return AutoSizeText(buildFullLocation(location), maxLines: 1);
}
How about try wrap the TextFiled widget in an Inkwell or GestureDetector widget?
GestureDetector(
onTap: (){},
child: TextField()),
I'm new to Flutter, but I'm trying to make an app with a ListView. The ListView is a list of exercises, within each exercise the number of sets can be added. The problem comes when i press the button add exercise. The above exercise with sets is just copied. I would like a new exercise tab with 0 sets. Below the code can be found.
Here is a picture of the list.
final decoratedField = InputDecoration(
filled: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: "null",
);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: [
titleSection,
// ignore: unnecessary_new
new TextField(
controller: eCtrl,
onSubmitted: (text) {
litems.add(text);
eCtrl.clear();
setState(() {});
},
),
Expanded(
// ignore: unnecessary_new
child: new ListView.builder(
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: EdgeInsets.all(10),
child: ExpansionTile(
initiallyExpanded: true,
title: Text(
litems[Index],
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
subtitle: Row(
children: [
Expanded(child: Text(" ")),
//Expanded(child: Text("data")),
//Expanded(child: Text("data")),
//Expanded(child: Text("data")),
],
),
// ignore: sort_child_properties_last
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: sets.length,
itemBuilder:
(BuildContext context, int Index1) {
return Dismissible(
key: UniqueKey(),
// only allows the user swipe from right to left
direction:
DismissDirection.endToStart,
// Remove this product from the list
// In production enviroment, you may want to send some request to delete it on server side
onDismissed: (_) {
setState(() {
sets.removeAt(Index1);
});
},
// ignore: sort_child_properties_last
child: Card(
elevation: 0,
child: Padding(
padding: EdgeInsets.all(1),
child: ListTile(
title: Text(
" ",
style: const TextStyle(
fontSize: 10,
fontWeight:
FontWeight.bold,
),
),
subtitle: Row(
children: [
Expanded(
child: Text(" "),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
],
),
))),
background: Container(
color: Colors.red,
margin:
const EdgeInsets.symmetric(
horizontal: 15,
),
alignment: Alignment.centerRight,
child: const Text(
"Delete",
style: TextStyle(
color: Colors.white,
),
)));
}),
Padding(
padding: EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
sets.add('sets-test');
setState(() {});
},
child: const Text('+ Add Set')),
),
const SizedBox(height: 5),
],
leading: IconButton(
icon: const Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
litems.removeAt(Index);
setState(() {});
},
),
)));
})),
ElevatedButton(
onPressed: () {
litems.add("new");
setState(() {});
},
child: const Text('Add Exercises')),
ElevatedButton(
onPressed: () {
createUser(user1, "5");
exercise.setExerciseTotals();
//saveExercise(exercise);
final workout = Workout([exercise, exercise1], "Det gik fint",
"10", 60, "type", "name", true, 0, 0, 0);
//workout.setWorkoutTotals();
saveWorkout(workout, userID);
},
child: const Text('pop')),
bottomSection,
],
),
));
}
You are not copy the item, you logic is that add new Item with null value, change decoratedField to this:
final decoratedField = InputDecoration(
filled: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: "0",
);
Im trying to build a listviewbuilder since a few days. For that i need the textfield input from another screen. I looked a lot of tutorials and question but it doesnt work.Im trying to put the input from multiple textfields into multiple lists to build a Listview builder. It would be the best if i can save all Textfield input when i press on flatbutton. I hope someone can help me.
First page
List<String> time = ["8:00"];List<String>
List<String> where = ["Am See"];
List<String> who = ["Eric"];
List<String> when = ["Donnerstag 21.4.21"];
body: SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(children: [
Upperscreen(size: size),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: where.length,
itemBuilder: (BuildContext context, int Index) {
return Column(children: [
SizedBox(
height: 40,
),
Container(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Meet1()));
},
child: Container(
width: size.width * 0.9,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(70)),
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomRight,
colors: [
Colors.green,
Colors.orange,
],
),
),
child: Column(children: <Widget>[
SizedBox(
height: 10,
),
Padding(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(
time[Index],
style: TextStyle(
color: Colors.white,
fontSize: 40,
fontWeight:
FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
who[Index],
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight:
FontWeight.bold),
),
Text(
when[Index],
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight:
FontWeight.bold),
),
Text(
where[Index],
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight:
FontWeight.bold),
Second page
child: Column(children: <Widget>[
SizedBox(
height: 10,
),
Padding(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
TextField(decoration: InputDecoration(hintText: " Time ")),
SizedBox(
height: 10,
),
TextField(
decoration: InputDecoration(hintText: " Who "),
),
SizedBox(
height: 10,
),
TextField(
decoration: InputDecoration(hintText: " Date "),
),
SizedBox(
height: 10,
),
TextField(
decoration: InputDecoration(hintText: " Where "),
),
SizedBox(height: 10)
],
),
),
]));
Here the Flatbutton to add all.
return FlatButton(
child: Icon(
Icons.check_circle_outline_rounded,
color: Colors.green,
size: 120,
),
onPressed: () {
Navigator.of(context).popUntil((route) => route.isFirst);
},
Use a TextEditingController(), just like this -
TextEditingController() myController = TextEditingController();
Then assign this controller to controller property in TextField() -
TextField(
controller: myController,
),
Then use myController.text to retrieve the text from TextField(), and pass it to other pages as a String parameter -
Example -
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
//....
body: FlatButton(
child: Icon(
Icons.check_circle_outline_rounded,
color: Colors.green,
size: 120,
),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (builder) {
return Screen2(text: myController.text);
}));
},
//....
),
);
}
}
Second Page -
class Screen2 extends StatelessWidget {
String text;
Screen2({this.text});
#override
Widget build(BuildContext context) {
return Scaffold(
//....
body: Text(text),
);
}
}
Go to this link to see another example
Now, here I used only 1 parameter "text". You can use multiple parameters like - "text1", "text2", "text3" and so on, as per your requirement, and use as many TextEditingController() for this.
*****Also Note that use of FlatButton() is depreciated, you can use a TextButton() instead
I have a widget which used to select a date, at beginning it's with 'no date chosen', and the widget in a column below it depends on it [which mean its show a list of timeSlots of Data if I selected a date]
But I got a setState called during build error, and This ReservationSlotWidget can not be marked as needing to build because the Framework is already in the process of building widgets
This is the selectDate widget
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.date_range,
color: Colors.white,
),
SizedBox(
width: 5,
),
Text(
_formatted == null
? 'No date chosen'
: _formatted,
style: TextStyle(
color: Colors.white,
))
],
),
FlatButton(
onPressed: ()=>_selectReservationDate(context),
child: Text(
'choose Date',
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
)
],
),
if(_selectedDate != null)
Divider(
color: parseColor('#2A2E43'),
thickness: 2.0,
),
if(_selectedDate != null)
Row(
children: <Widget>[
Icon(
Icons.alarm,
color: Colors.white,
),
SizedBox(
width: 5,
),
Text('$_numberOfSeats Available Time Slots',
style: TextStyle(
color: Colors.white,
))
],
),
this is a listview items which appeared depend on the date I chose.
if(_formatted != null)
Expanded(
child: Consumer<SlotProvider>(
builder: (ctx, slotProvider, _)=>
ListView.builder(
itemCount: slotProvider.slots.length,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index) {
setState(() {
_numberOfSeats = slotProvider.slots[index].seats;
});
return GestureDetector(
onTap: () {
setState(() {
if(_isInit){
_isExpanded = !_isExpanded;
}
_expandedIndex = index;
_isInit = false;
});
},
child: Container(
padding: EdgeInsets.all(4),
margin: EdgeInsets.all(4),
decoration: BoxDecoration(
color: _expandedIndex == index
? Theme.of(context).primaryColor
: parseColor('#2A2E43'),
borderRadius:
BorderRadius.all(Radius.circular(10))),
child: SlotsWidget(
fromTime: slotProvider.slots[index].fromTime.toString(),
toTime:slotProvider.slots[index].toTime.toString(),
seats:slotProvider.slots[index].seats,
))
);
}
),
)
),
the comment of #void is right and you can avoid the repeated setState with if block;
if (_numberOfSeats != slotProvider.slots[index].seats)
setState(() {
_numberOfSeats = slotProvider.slots[index].seats;
});
First of all, I created a designed bottom sheet, In which, there are two lists to show numbers(left side) and options(hour, day, week, month) with the help of CupertinoPicker widget,
Numbers will depend on what option I select, If I select the hour, numbers of the left side should be 1-24, and if I select week, numbers should be 1-4, I select the day, numbers should be 1-30 and last I select month number should be 1-12.
Code :
All Lists variable:
List<String> reminderDay = ['hour','day','week','month'];
List<String> reminderHoursVal =['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24'];
List<String> reminderDaysVal =['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'];
List<String> reminderMonthsVal =['1','2','3','4','5','6','7','8','9','10','11','12'];
List<String> reminderWeeksVal =['1','2','3','4'];
String selectedReminderVal='1';
String selectedReminderDay ='hour';
Code of bottom sheet:
addReminder(){
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: Container(
padding: const EdgeInsets.only(top:8,right: 8, left:8,bottom: 8),
height: MediaQuery.of(context).size.height/2,
// color: Colors.transparent,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30)
)
),
child: Container(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height:10),
Text("Set a reminder",
style: TextStyle(
fontSize:18,
fontWeight:FontWeight.bold,
color: Colors.grey
),
),
SizedBox(height:20),
Container(
margin: const EdgeInsets.only(left: 10, right: 10),
height: MediaQuery.of(context).size.height/4,
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(10)
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,
),
itemExtent: 30,
backgroundColor: Colors.grey[100],
onSelectedItemChanged: (int val) {
setState(() {
if(selectedReminderDay=='day'){
selectedReminderVal = reminderDaysVal[val];
}else if(selectedReminderDay=='week'){
selectedReminderVal = reminderWeeksVal[val];
}else if(selectedReminderDay=='month'){
selectedReminderVal = reminderMonthsVal[val];
}else{
selectedReminderVal = reminderHoursVal[val];
}
print("selectedReminderVal:$selectedReminderVal");
});
},
children:selectedReminderDay=='day'?reminderDaysVal
:selectedReminderDay=='week'?reminderWeeksVal
:selectedReminderDay=='month'?reminderMonthsVal:reminderHoursVal// ['hour','day','week','month']; reminderHoursVal
.map(
(item) => Center(
child: Text(
item,
style: TextStyle(
fontSize: 16,
// fontWeight:FontWeight.bold,
),
),
),
)
.toList()),
),
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,
),
itemExtent: 30,
backgroundColor: Colors.grey[100],
onSelectedItemChanged: (int val) {
setState(() {
selectedReminderDay = reminderDay[val];
print("selectedReminderDay:$selectedReminderDay");
});
},
children: reminderDay
.map(
(item) => Center(
child: Text(
item,
style: TextStyle(
fontSize: 16,
// fontWeight:FontWeight.bold,
),
),
),
)
.toList()),
),
])
),
SizedBox(height:15),
// selectedVal!=null?Text(selectedVal.toString()):Container()
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("You'll get the reminder"),
Text('$selectedReminderVal $selectedReminderDay before the event')
],
),
SizedBox(height:25),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: (){
Navigator.pop(context);
},
child: Text("Cancel",
style: TextStyle(
fontSize: 18,
color: Colors.blue,
fontWeight: FontWeight.bold
),
),
),
InkWell(
onTap: (){
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8)
),
width: MediaQuery.of(context).size.width/5,
height: MediaQuery.of(context).size.height/25 ,
child: Text("Save", style:TextStyle(
color: Colors.white,
fontSize: 19
)),
),
)
],
),
)
],
),
)
),
);
},
);
}
Screenshot:
This is because the state you are setting is different from the state in the modal bottom sheet.
Right now, when you are calling setState, you are actually rebuilding the stateful widget under the modal bottom sheet.
To fix this, just wrap your bottom sheet in a Stateful Builder.
StatefulBuilder(
builder: (context, setState) {
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: Container(
padding: const EdgeInsets.only(top:8,right: 8, left:8,bottom: 8),
height: MediaQuery.of(context).size.height/2,
// color: Colors.transparent,
decoration: BoxDecoration(
color: Colors.white,
....
when we create new context widgets in existing state there states become different, bottomSheets are similar to dialogBox with new context and builder build a completely new widget out of the parent state, to create its own stateful state Wrap it with the stateful builder and user its own setState to change anything in this context not the parent one
eg:
StatefulBuilder(
builder: (context, setStateChild) {
return AnimatedPadding(...
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,
),
itemExtent: 30,
backgroundColor: Colors.grey[100],
onSelectedItemChanged: (int val) {
setStateChild(() {
selectedReminderDay = reminderDay[val];
print("selectedReminderDay:$selectedReminderDay");
});
},);
child: ... ),
}