Flutter showModalBottomSheet is hidden behind CupertinoTabBar

4k views Asked by At

I use CupertinoTabBar, but want to show material design BottomSheet when user's device is Android. However, when I used both of them, BottomSheet is hidden behind CupertinoTabBar like below.

Could you help me to fix this? Or is it bad to use both of them?

enter image description here

My simplified code

class MyApp extends StatelessWidget {
  void onPressed(BuildContext context) async {
    await showModalBottomSheet(
      context: context,
      builder: (context) => Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          ListTile(
            title: Text('Delete'),
            onTap: () => Navigator.of(context).pop('delete'),
          ),
          Divider(),
          ListTile(
            title: Text('Cancel'),
            onTap: () => Navigator.of(context).pop('cancel'),
          )
        ],
      ),
    );
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.music_note),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings),
            ),
          ]
        ),
        tabBuilder: (context, index) {
          switch (index) {
            case 0:
              return CupertinoTabView(
                builder: (context) {
                  return CupertinoPageScaffold(
                    child: FlatButton(
                      child: Text('button'),
                      onPressed: () => onPressed(context),
                    ),
                  );
                },
              );
            case 1:
              return CupertinoTabView(
                builder: (context) {
                  return CupertinoPageScaffold(
                    child: Text('tab 2'),
                  );
                },
              );
          }
          return Container();
        }
      )
    );
  }
}
2

There are 2 answers

0
Suraj Nair On BEST ANSWER

You just need to set useRootNavigator to true. This will display model sheet above all other content.

The useRootNavigator parameter ensures that the root navigator is used to display the bottom sheet when set to true. This is useful in the case that a modal bottom sheet needs to be displayed above all other content but the caller is inside another Navigator.

Refactored code:

    void onPressed(BuildContext context) async {
     await showModalBottomSheet(
      useRootNavigator: true,
      context: context,
      builder: (context) => Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          ListTile(
            title: Text('Delete'),
            onTap: () => Navigator.of(context).pop('delete'),
          ),
          Divider(),
          ListTile(
            title: Text('Cancel'),
            onTap: () => Navigator.of(context).pop('cancel'),
          )
        ],
      ),
    );
}
0
Salim Murshed On

You can set some padding below or set container height for this. I edit your code setting some padding, please check it.

class MyApp extends StatelessWidget {
  void onPressed(BuildContext context) async {
    await showModalBottomSheet(
      context: context,
      builder: (context) => Padding(
        padding:  EdgeInsets.fromLTRB(0, 0, 0, 60),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            ListTile(
              title: Text('Delete'),
              onTap: () => Navigator.of(context).pop('delete'),
            ),
            Divider(),
            ListTile(
              title: Text('Cancel'),
              onTap: () => Navigator.of(context).pop('cancel'),
            )
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.music_note),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.settings),
              ),
            ]),
            tabBuilder: (context, index) {
              switch (index) {
                case 0:
                  return CupertinoTabView(
                    builder: (context) {
                      return CupertinoPageScaffold(
                        child: FlatButton(
                          child: Text('button'),
                          onPressed: () => onPressed(context),
                        ),
                      );
                    },
                  );
                case 1:
                  return CupertinoTabView(
                    builder: (context) {
                      return CupertinoPageScaffold(
                        child: Text('tab 2'),
                      );
                    },
                  );
              }
              return Container();
            }));
  }
}