Ankit Dubey
Ankit Dubey

Reputation: 1170

No Scaffold widget found : Getting exception while opening Bottom Dialog sheet

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.

Upvotes: 26

Views: 15710

Answers (4)

Pedro Massango
Pedro Massango

Reputation: 5015

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 of 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();
            })));
      }
    }

Upvotes: 32

Anant
Anant

Reputation: 31

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,
                              ));
                        },

Upvotes: 1

Isis Curiel
Isis Curiel

Reputation: 160

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,
                              ));
}
   );
  }
}

Upvotes: 0

Aamil Silawat
Aamil Silawat

Reputation: 8229

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: () => {},
            ),
          ],
        ),
      );
    });
}

Upvotes: 60

Related Questions