title: How to make custom Bottom Navigation Bar in Flutter
body: <p>I have a design of Bottom Navigation Bar like this: </p>
  
  <p><a href="https://i.stack.imgur.com/zj1ze.png" rel="noreferrer"><img src="https://i.stack.imgur.com/zj1ze.png" alt="enter image description here"></a></p>
  
  <p>I try my best to create custom of Bottom Navigation Bar with this code:</p>
  
  <pre><code>class FABBottomAppBarItem {
    FABBottomAppBarItem({this.iconData, this.text});
    IconData iconData;
    String text;
  }
  
  class FABBottomAppBar extends StatefulWidget {
    FABBottomAppBar({
      this.items,
      this.centerItemText,
      this.height: 60.0,
      this.iconSize: 24.0,
      this.backgroundColor,
      this.color,
      this.selectedColor,
      this.notchedShape,
      this.onTabSelected,
    }) {
      assert(this.items.length == 2 || this.items.length == 4);
    }
    final List&lt;FABBottomAppBarItem&gt; items;
    final String centerItemText;
    final double height;
    final double iconSize;
    final Color backgroundColor;
    final Color color;
    final Color selectedColor;
    final NotchedShape notchedShape;
    final ValueChanged&lt;int&gt; onTabSelected;
  
    @override
    State&lt;StatefulWidget&gt; createState() =&gt; FABBottomAppBarState();
  }
  
  class FABBottomAppBarState extends State&lt;FABBottomAppBar&gt; {
    int _selectedIndex = 0;
  
    _updateIndex(int index) {
      widget.onTabSelected(index);
      setState(() {
        _selectedIndex = index;
      });
    }
  
    @override
    Widget build(BuildContext context) {
      List&lt;Widget&gt; items = List.generate(widget.items.length, (int index) {
        return _buildTabItem(
          item: widget.items[index],
          index: index,
          onPressed: _updateIndex,
        );
      });
      items.insert(items.length &gt;&gt; 1, _buildMiddleTabItem());
  
      return BottomAppBar(
        shape: widget.notchedShape,
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: items,
        ),
        color: widget.backgroundColor,
      );
    }
  
    Widget _buildMiddleTabItem() {
      return Expanded(
        child: SizedBox(
          height: widget.height,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.center,
            children: &lt;Widget&gt;[
              SizedBox(height: widget.iconSize),
              Text(
                widget.centerItemText ?? '',
                style: TextStyle(color: widget.color),
              ),
            ],
          ),
        ),
      );
    }
  
    Widget _buildTabItem({
      FABBottomAppBarItem item,
      int index,
      ValueChanged&lt;int&gt; onPressed,
    }) {
      Color color = _selectedIndex == index ? widget.selectedColor : widget.color;
      return Expanded(
        child: SizedBox(
          height: widget.height,
          child: Material(
            type: MaterialType.transparency,
            child: InkWell(
              onTap: () =&gt; onPressed(index),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                mainAxisAlignment: MainAxisAlignment.center,
                children: &lt;Widget&gt;[
                  Icon(item.iconData, color: color, size: widget.iconSize),
                  Text(
                    item.text,
                    style: TextStyle(color: color),
                  )
                ],
              ),
            ),
          ),
        ),
      );
    }
  }
  </code></pre>
  
  <p>And I implemented that custom like this:</p>
  
  <pre><code>bottomNavigationBar: FABBottomAppBar(
            centerItemText: 'เสา',
            color: Colors.grey,
            backgroundColor: Colors.white,
            selectedColor: Colors.red,
            notchedShape: CircularNotchedRectangle(),
            onTabSelected: _onTapped,
            items: [
              FABBottomAppBarItem(iconData: Icons.home, text: 'หน้าแรก'),
              FABBottomAppBarItem(iconData: Icons.search, text: 'ค้นหา'),
              FABBottomAppBarItem(iconData: Icons.account_circle, text: 'โปรไฟล์'),
              FABBottomAppBarItem(iconData: Icons.more_horiz, text: 'อื่นๆ'),
            ],
          ),
          body: _list[_page],
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
          floatingActionButton: FloatingActionButton(
            onPressed: () {
            },
            child: Icon(Icons.add),
            elevation: 2.0,
          ),
        ),
  </code></pre>
  
  <p>And the result of that code is:</p>
  
  <p><a href="https://i.stack.imgur.com/APv1r.png" rel="noreferrer"><img src="https://i.stack.imgur.com/APv1r.png" alt="enter image description here"></a></p>
  
  <p>How to make my Custom Nav Bar like the design? Because in the design, the <code>FAB/Asset/Icon</code> inside the Bottom Navigation Bar and have <code>curved upwards</code> as I marked with <code>arrows</code> in the design.</p>