Why is selected value not reflecting in showModalBottomSheet with flutter?

Viewed 1150

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:

enter image description here

2 Answers

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: ... ),

}

Related