skip to Main Content

I would like to create a navbar which can be expandable.
The goal is to show 5 icons, then 3 more when I tap on the burger icon.

There is some screen that can help for the result I want:

enter image description here

2

Answers


  1. You can use Column with two Row on bottomNavigationBar. Also you may like Wrap widget. You can wrap each item with tappable widget to perform action body.

    class AppNT extends StatefulWidget {
      const AppNT({super.key});
    
      @override
      State<AppNT> createState() => _AppNTState();
    }
    
    class _AppNTState extends State<AppNT> {
      bool expand = false;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          bottomNavigationBar: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  for (int i = 0; i < 4; i++)
                    Container(
                      height: 50,
                      color: Colors.blue,
                      child: Center(
                        child: Text(
                          'Tab $i',
                          style: const TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  IconButton(
                      onPressed: () {
                        setState(() {
                          expand = !expand;
                        });
                      },
                      icon: Icon(Icons.more_horiz)),
                ],
              ),
              if (expand)
                Row( // you can add some animatedWidget
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    for (int i = 0; i < 2; i++)
                      Container(
                        height: 50,
                        color: Colors.blue,
                        child: Center(
                          child: Text(
                            'Tab ${i + 4}',
                            style: const TextStyle(color: Colors.white),
                          ),
                        ),
                      ),
                  ],
                ),
            ],
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. You can use the BottomAppBar widget in combination with the FloatingActionButton widget, here is an example, do some customization as you wish:

    class ExpandableNavbar extends StatefulWidget {
      @override
      _ExpandableNavbarState createState() => _ExpandableNavbarState();
    }
    
    class _ExpandableNavbarState extends State<ExpandableNavbar> {
      bool _isExpanded = false;
    
      @override
      Widget build(BuildContext context) {
        List<Widget> _icons = [
          IconButton(icon: Icon(Icons.home), onPressed: () {}),
          IconButton(icon: Icon(Icons.search), onPressed: () {}),
          IconButton(icon: Icon(Icons.settings), onPressed: () {}),
          IconButton(icon: Icon(Icons.person), onPressed: () {}),
          IconButton(icon: Icon(Icons.notifications), onPressed: () {}),
        ];
    
        List<Widget> _expandedIcons = [
          IconButton(icon: Icon(Icons.email), onPressed: () {}),
          IconButton(icon: Icon(Icons.help), onPressed: () {}),
        ];
    
        return Scaffold(
          appBar: AppBar(
            title: Text("My App"),
          ),
          body: Center(
            child: Text("My Content"),
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(_isExpanded ? Icons.close : Icons.menu),
            onPressed: () {
              setState(() {
                _isExpanded = !_isExpanded;
              });
            },
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
          bottomNavigationBar: BottomAppBar(
            shape: CircularNotchedRectangle(),
            notchMargin: 8.0,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: _icons,
                ),
                if (_isExpanded)
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: _expandedIcons,
                  ),
              ],
            ),
          ),
        );
      }
    }
    

    Variant without Floating Button:

    class ExpandableNavbar extends StatefulWidget {
      @override
      _ExpandableNavbarState createState() => _ExpandableNavbarState();
    }
    
    class _ExpandableNavbarState extends State<ExpandableNavbar> {
      bool _isExpanded = false;
    
      @override
      Widget build(BuildContext context) {
        List<Widget> _icons = [
          IconButton(icon: Icon(Icons.home), onPressed: () {}),
          IconButton(icon: Icon(Icons.search), onPressed: () {}),
          IconButton(icon: Icon(Icons.settings), onPressed: () {}),
          IconButton(icon: Icon(Icons.person), onPressed: () {}),
          IconButton(
              icon: Icon(_isExpanded ? Icons.close : Icons.menu),
              onPressed: () {
                setState(() {
                  _isExpanded = !_isExpanded;
                });
              }),
        ];
    
        List<Widget> _expandedIcons = [
          IconButton(icon: Icon(Icons.email), onPressed: () {}),
          IconButton(icon: Icon(Icons.help), onPressed: () {}),
        ];
    
        return Scaffold(
          appBar: AppBar(
            title: Text("My App"),
          ),
          body: Center(
            child: Text("My Content"),
          ),
          bottomNavigationBar: BottomAppBar(
            shape: CircularNotchedRectangle(),
            notchMargin: 8.0,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: _icons,
                ),
                if (_isExpanded)
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: _expandedIcons,
                  ),
              ],
            ),
          ),
        );
      }
    }
    

    You can see how it works here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search