flutterbottom-sheetflutter-bottomnavigation

How can we make the BottomSheet modal not cover the bottom navigation bar


I have a bottomSheet modal which I am calling from BottomNavigationBar. I still want to be able to access the bottom navigation bar even when the modal is open . I tried using useRootNavigator: true, but I still can not access the bottom navigation bar. I am calling the modal as follows:

void _onItemTapped(int index) async {
    setState(() {
      _selectedIndex = index;
    });

    if (index == 4) {
      if (_controller.isCompleted) {
        _controller.reverse();
      } else {
        _controller.forward();
        await showModalBottomSheet(
          useRootNavigator: true,
          context: context,
          isScrollControlled: true,
          backgroundColor: Colors.transparent,
          builder: (context) => DraggableScrollableSheet(
            initialChildSize:
                0.9, 
            maxChildSize:
                0.9, 
            minChildSize: 0.3, // Minimum height of the modal.
            builder: (_, controller) => ListView(
              controller: controller,
              children: [
                MoreOptionsModal(),
              ],
            ),
          ),
        );
        _controller.reverse();
      }
    } else {
      _controller.reverse();
    }
  }

...
 body: SafeArea(child: _screens.elementAt(_selectedIndex).body!),
 bottomNavigationBar: BottomNavigationBar(
        items: _buildBottomNavItems(),
        currentIndex: _selectedIndex,
        onTap: 
          _onItemTapped
        ,)

I believe this is related to the discussion here https://github.com/flutter/flutter/issues/140812 which was unfortunately closed without solving the problem.


Solution

  • As the showModalBottomSheet function's documentation mentions, it is an alternative to a menu or a dialog, which prevents the user from interacting with the rest of the app while it's open.

    In your case, I believe what you need is ScaffoldState.showBottomSheet. This method shows a Material Design bottom sheet in the nearest Scaffold, allowing the bottom navigation bar to remain accessible.

    Here is an example demonstrating how to achieve the desired behavior:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        const MaterialApp(
          home: ExampleApp(),
        ),
      );
    }
    
    class ExampleApp extends StatefulWidget {
      const ExampleApp({super.key});
    
      @override
      State<ExampleApp> createState() => _ExampleAppState();
    }
    
    class _ExampleAppState extends State<ExampleApp> {
      final _scaffoldKey = GlobalKey<ScaffoldState>();
      int _currentIndex = 0;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: const Text('Example App'),
          ),
          bottomNavigationBar: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Home',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.business),
                label: 'Business',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.school),
                label: 'School',
              ),
            ],
            currentIndex: _currentIndex,
            onTap: (index) {
              setState(() => _currentIndex = index);
    
              _scaffoldKey.currentState?.showBottomSheet(
                showDragHandle: true,
                (_) => SizedBox(
                  height: 100,
                  width: double.infinity,
                  child: Center(
                    child: Text('Bottom Sheet Index: $_currentIndex'),
                  ),
                ),
              );
            },
          ),
          body: Center(
            child: Text('Page Index: $_currentIndex'),
          ),
        );
      }
    }
    

    Example GIF