skip to Main Content

I have two showModalBottomSheet(). In the First modalSheet there is a IconButton(). When the IconButton tapped, The First sheet should be closed and after 2 seconds the second modalSheet should be opened.

When I use the Future.delay function between the Navigator.pop(context) and the second showModalBottomSheet(), It throws some error and the second sheet is not opening.

Code:

IconButton(
           onPressed: () {
                        taskerFilterController.applyingLangaugePairChanges().whenComplete(
                          () {
                            Navigator.pop(context);
                            Future.delayed(const Duration(seconds: 2), () {
                              if (mainLayoutController.contactType == 1 && mainLayoutController.locationName.isEmpty) {
                                showModalBottomSheet(context: context, builder: (BuildContext context) => const TaskType(), isScrollControlled: true);
                              }
                            });
                          },
                        );
                      },
                      icon: const Icon(Icons.done, size: 25, color: kGreen)),

If I remove the Future.delay it was working fine or if I remove the Navigator.pop(context) it was fine but the first modalSheet has to be closed before opening the second modalSheet.

Error:

    Null check operator used on a null value
I/flutter (32026): #0      Element.widget (package:flutter/src/widgets/framework.dart:3483:31)
I/flutter (32026): #1      debugCheckHasMediaQuery.<anonymous closure> (package:flutter/src/widgets/debug.dart:296:17)
I/flutter (32026): #2      debugCheckHasMediaQuery (package:flutter/src/widgets/debug.dart:311:4)
I/flutter (32026): #3      showModalBottomSheet (package:flutter/src/material/bottom_sheet.dart:1254:10)
I/flutter (32026): #4      CatAndSubcat.build.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:tolk2go/Utility/cat_and_subcat.dart:37:33)
I/flutter (32026): #5      new Future.delayed.<anonymous closure> (dart:async/future.dart:422:39)
I/flutter (32026): #6      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
I/flutter (32026): #7      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
I/flutter (32026): #8      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
I/flutter (32026): #9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

How do solve this? Is there any way to close the showModalBottomSheet() without using the Navigator.pop(context)?

2

Answers


  1. To show the second modal bottom sheet, use the context from the widget instead of the context from the first modal bottom sheet. To do this, you can rename the inner context to prevent variable shadowing.

    class MyWidget extends StatelessWidget {
      const MyWidget({super.key});
    
      @override
      Widget build(BuildContext context) {
        return FilledButton(
          onPressed: () {
            showModalBottomSheet(
              context: context,
              builder: (modalContext) { // Rename `context` to `modalContext`
                return IconButton(
                  onPressed: () {
                    Navigator.pop(modalContext); // Use `modalContext` to pop the first modal
                    Future.delayed(const Duration(seconds: 2), () {
                      showModalBottomSheet(
                        context: context, // This context is from MyWidget's build method
                        builder: (_) => const TaskType(),
                      );
                    });
                  },
                  icon: Icon(Icons.done),
                );
              },
            );
          },
          child: Text('Show first bottom sheet'),
        );
      }
    }
    
    Login or Signup to reply.
  2. The issue is likely due to the context being disposed when you pop the first modal sheet. This can be resolved by using a GlobalKey to provide a valid context for the second showModalBottomSheet.

        final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
    
        // ...
    
        IconButton(
          onPressed: () {
            taskerFilterController.applyingLangaugePairChanges().whenComplete(
              () async {
                Navigator.pop(context);
                await Future.delayed(const Duration(seconds: 2));
                if (mainLayoutController.contactType == 1 && mainLayoutController.locationName.isEmpty) {
                  scaffoldKey.currentState.showBottomSheet((context) => const TaskType());
                }
              },
            );
          },
          icon: const Icon(Icons.done, size: 25, color: Green)
        ),
    
        // ...
        
        Scaffold(
          key: scaffoldKey,
          // ...
        )
    

    Remember to assign the scaffoldKey to your Scaffold widget’s key property.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search