Why is selected value not reflecting in showModalBottomSheet with flutter?

935

Solution 1

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

}

Solution 2

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,

....
Share:
935
Shruti Ramnandan Sharma
Author by

Shruti Ramnandan Sharma

I'm an Indian developer for building mobile applications with flutter. linkedin-profile

Updated on December 23, 2022

Comments

  • Shruti Ramnandan Sharma
    Shruti Ramnandan Sharma over 1 year

    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

    • Shri Hari L
      Shri Hari L over 3 years
      Try to enclose the condition within parenthesis. (selectedReminderDay=='day'?reminderDaysVal : selectedReminderDay=='week'?reminderWeeksVal : selectedReminderDay=='month'? reminderMonthsVal : reminderHoursVal).map()
    • Shruti Ramnandan Sharma
      Shruti Ramnandan Sharma over 3 years
      No, it is not working .
  • Shruti Ramnandan Sharma
    Shruti Ramnandan Sharma over 3 years
    You are great, Thank you so much :)