21

I'm using Scaffold widget but while opening a bottom dialog sheet I'm getting this exception

@override
Widget build(BuildContext context) {

return Scaffold(
  appBar: AppBar(
    title: Text("Calendar"),
  ),
  body: SafeArea(
  .......
  .......

    child: GestureDetector(
                        onTap: (){
                          //getting exception here
                          showBottomSheet(
                              context: context,
                              builder: (context) => Container(
                                color: Colors.red,
                              ));
                        },

I'm stuck on this code, it'll be very helpful if someone can give any suggestion. Thank you.

Ankit Dubey
  • 1,000
  • 1
  • 8
  • 12

4 Answers4

48

Use showModalBottomSheet instead of showBottomSheet try out below eg.

void _settingModalBottomSheet(BuildContext context){
    showModalBottomSheet(
        context: context,
        builder: (BuildContext bc){
      return Container(
        child: new Wrap(
          children: <Widget>[
            new ListTile(
                leading: new Icon(Icons.music_note),
                title: new Text('Music'),
                onTap: () => {}
            ),
            new ListTile(
              leading: new Icon(Icons.videocam),
              title: new Text('Video'),
              onTap: () => {},
            ),
          ],
        ),
      );
    });
}
Aamil Silawat
  • 7,735
  • 3
  • 19
  • 37
  • 7
    why it works??... what is the difference. – Asbah Riyas Mar 19 '21 at 06:14
  • Why this works is because `showModalBottomSheet` looks up for nearest `Navigator` and `Theme`...unlike `showBottomSheet` which looks for nearest `Scaffold`... i.e. to use `showBottomDialog` you should use context from a Scaffold like what this [answer](https://stackoverflow.com/a/60072540/10603758) – Jerin Mar 25 '23 at 21:37
25

The problem is that the context used to show the BottomSheet is not the context of the Scaffold. You can solve this issue by using GlobalKey or wrap your GestureDetector in a Builder widget so that it gives you the context that contains a reference of the Scaffold.

Here is a example using GlobalKey with the state of the Scaffold:

// created the ScaffoldState key    
final scaffoldState = GlobalKey<ScaffoldState>();
    
    class MyWidget extends StatelessWidget {
      void _showSheet() {
        // Show BottomSheet here using the Scaffold state instead ot«f the Scaffold context
        scaffoldState.currentState
            .showBottomSheet((context) => Container(color: Colors.red));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            key: scaffoldState,
            appBar: AppBar(
              title: Text("Calendar"),
            ),
            body: SafeArea(child: GestureDetector(onTap: () {
              //getting exception here
              _showSheet();
            })));
      }
    }
Pedro Massango
  • 4,114
  • 2
  • 28
  • 48
  • 1
    I ran in to different error, while using your code The method 'addLocalHistoryEntry' was called on null. Receiver: null Tried calling: addLocalHistoryEntry(Instance of 'LocalHistoryEntry') – imgkl Apr 17 '20 at 17:55
  • Wich class are you using to call addLocalHistoryEntry? – Pedro Massango Apr 17 '20 at 18:45
  • This what what I needed - I wanted to offset the bottom sheet by the navigationbar and not have it "scroll in" over the top of that and showModalBottomSheet did not allow seem to allow that even with inset. – Kram Jul 07 '23 at 09:28
1

Wrap the widget tree with Builder widget

 @override
Widget build(BuildContext context) {

return Scaffold(
  appBar: AppBar(
    title: Text("Calendar"),
  ),
  body: Builder(  //HERE
     builder:(context){
    
     return SafeArea(
     .......
     .......

    child: GestureDetector(
                        onTap: (){
                          //getting exception here
                          showBottomSheet(
                              context: context,
                              builder: (context) => Container(
                                color: Colors.red,
                              ));
                        },
Anant
  • 31
  • 1
  • 4
0

I am not 100% aware of why this works but I am guessing because its outside of the scaffold.

 class Example extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            
            appBar: AppBar(
              
            ),
            body: SafeArea(child: YourWidget(),
)
);
      }
    }

class YourWidget extends StatelessWidget {
  const YourWidget({
    Key key,
  }) : super(key: key);
   @override
  Widget build(BuildContext context) {
 return GestureDetector(
                        onTap: (){
                          //getting exception here
                          showBottomSheet(
                              context: context,
                              builder: (context) => Container(
                                color: Colors.red,
                              ));
}
   );
  }
}
Isis Curiel
  • 160
  • 2
  • 14