Search code examples
flutterbottomnavigationviewbottom-sheetflutter-showmodalbottomsheet

Show Bottom Modal Sheet above the Bottom Navigation Bar


Here in the below image I have added showModalBottomSheet on clicking on the item of "Bottom Navigation Bar", but the BottomNavigationBar is hidden by the modal sheet, So I want to make it visible even the bottom sheet is present. Can anyone please anyone help me out.

enter image description here

This is my bottom navigation code:

Widget _bottomNavigationBar() {
  return BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      key: scaffoldState,
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Home',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.branding_watermark_outlined),
          label: 'Brands',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.category),
          label: 'Category',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: 'Profile',
        )
      ],
      currentIndex: _selectedIndex,
      selectedItemColor: AppColors.blue,
      onTap: (newIndex) => {
            if (newIndex == 1)
              {showBrandsBottomSheet(context)}
            else if (newIndex == 2)
              {showCategoryBottomSheet(context)}
            else
              {
                setState(() {
                  _selectedIndex = newIndex;
                })
              }
          });
}

Here is my code for bottom model sheet:

showBrandsBottomSheet(BuildContext context) {
  return showModalBottomSheet<void>(
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.only(
          topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
    ),
    context: context,
    useRootNavigator: true,
    isScrollControlled: true,
    builder: (BuildContext _) {
      return Container(
        color: Colors.white,
        height: MediaQuery.of(context).size.height / 2,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 5, top: 3),
                child: GestureDetector(
                  onTap: () {
                    Navigator.pop(context);
                  },
                  child: const Align(
                      alignment: Alignment.topRight,
                      child: Icon(Icons.close)),
                ),
              ),
              Container(
                color: Colors.white,
                height: 350,
                child: ListView.builder(
                  key: Key('builder ${_selected.toString()}'), //a
                  scrollDirection: Axis.vertical,
                  // shrinkWrap: true,
                  // physics: NeverScrollableScrollPhysics(),
                  itemCount: brandList.length,
                  itemBuilder: (BuildContext context, int index) {
                    return Theme(
                        data: Theme.of(context)
                            .copyWith(dividerColor: Colors.white),
                        child: ExpansionTile(
                          // tilePadding: const EdgeInsets.all(0),
                          key: Key(index.toString()), //attention
                          initiallyExpanded: index == _selected, //attention
                          collapsedIconColor: Colors.blue,
                          iconColor: Colors.blue,
                          backgroundColor: Colors.white,
                          title: Text(
                            brandList[index],
                            style: const TextStyle(
                                fontSize: 13.0,
                                color: Colors.black,
                                fontWeight: FontWeight.w600),
                          ),
                          children: <Widget>[
                            Container(
                              color: Colors.blue[50],
                              child: Column(
                                children: _buildExpandableBrands(brandList),
                              ),
                            ),
                          ],
                          onExpansionChanged: ((newState) {
                            if (newState) {
                              setState(() {
                                const Duration(seconds: 20000);
                                _selected = index;
                              });
                            } else {
                              setState(() {
                                _selected = -1;
                              });
                            }
                          }),
                        ));
                  },
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}

Solution

  • Finally, this question helped me in getting this done.

    Here is my working code:

    Widget _bottomNavigationBar() {
        return BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            key: scaffoldState,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Home',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.branding_watermark_outlined),
                label: 'Brands',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.category),
                label: 'Category',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.person),
                label: 'Profile',
              )
            ],
            currentIndex: _selectedIndex,
            selectedItemColor: AppColors.blue,
            onTap: (newIndex) => {
                  if (newIndex == 1)
                    {
                      _scaffoldKey.currentState?.showBottomSheet((_) => Container(
                            child: showBrandsBottomSheet(),
                          ))
                    }
                  else if (newIndex == 2)
                    {
                      {
                        _scaffoldKey.currentState?.showBottomSheet((_) => Container(
                              child: showCategoryBottomSheet(),
                            ))
                      }
                    }
                  else
                    {
                      setState(() {
                        _selectedIndex = newIndex;
                      })
                    }
                });
      }
    

    showBrandsBottomSheet:

    showBrandsBottomSheet() {
        return Container(
          color: Colors.white,
          height: MediaQuery.of(context).size.height / 2,
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(right: 5, top: 3),
                  child: GestureDetector(
                    onTap: () {
                      Navigator.pop(context);
                    },
                    child: const Align(
                        alignment: Alignment.topRight, child: Icon(Icons.close)),
                  ),
                ),
                Container(
                  color: Colors.white,
                  height: 350,
                  child: ListView.builder(
                    key: UniqueKey(),
                    scrollDirection: Axis.vertical,
                    itemCount: brandList.length,
                    itemBuilder: (BuildContext context, int index) {
                      cardKeyList.add(GlobalKey(debugLabel: "index :$index"));
                      return Theme(
                          data: Theme.of(context)
                              .copyWith(dividerColor: Colors.white),
                          child: ExpansionTileCard(
                            key: cardKeyList[index],
                            initiallyExpanded: false,
                            title: Text(
                              brandList[index],
                              style: const TextStyle(
                                  fontSize: 13.0,
                                  color: Colors.black,
                                  fontWeight: FontWeight.w600),
                            ),
                            children: <Widget>[
                              Container(
                                color: Colors.blue[50],
                                child: Column(
                                  children: _buildExpandableBrands(brandList),
                                ),
                              ),
                            ],
                            onExpansionChanged: (value) {
                              if (value) {
                                Future.delayed(const Duration(milliseconds: 200),
                                    () {
                                  for (var i = 0; i < cardKeyList.length; i++) {
                                    if (index != i) {
                                      cardKeyList[i].currentState?.collapse();
                                    }
                                  }
                                });
                              }
                            },
                          ));
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      }
    

    Now it is started showing above the bottom navigation.