Flutter showModalBottomSheet is hidden behind CupertinoTabBar

Issue

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

Solution

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

Answered By – Suraj Nair

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *