Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter BottomNavigationBar center icon style

Is there a way to add a notch above the center icon in BottomNavigationBar? Something like in this image:

sc

I currently have something like this generating the navigation:

        return BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          fixedColor: Color(0xff2398C3),
          showSelectedLabels: false,
          showUnselectedLabels: false,
          currentIndex: snapshot.data.index,
          onTap: _bottomNavBarBloc.pickItem,
          items: [
            BottomNavigationBarItem(
              title: Text('Search'),
              icon: Icon(Icons.search),
            ),
            BottomNavigationBarItem(
              title: Text('Browse'),
              icon: Icon(Icons.view_list),
            ),
            BottomNavigationBarItem(
              title: Text('Icon'),
              icon: Container(
                child: FlutterLogo(
                  size: 35.0,
                ),
              ),
            ),
            BottomNavigationBarItem(
              title: Text('Favorites'),
              icon: Icon(Icons.bookmark),
            ),
            BottomNavigationBarItem(
              title: Text('Settings'),
              icon: Icon(Icons.settings),
            ),
          ],
        );
like image 236
William Avatar asked Oct 28 '25 05:10

William


1 Answers

You can use BottomAppBar in place of BottomNavigationBar to achieve this.you can see the full documentation here.

There is a property called shape in the ButtomAppBar where you can pass an Object of CircularNotchedRectangle to achieve the notch.But by default it'll give a inside notch so you have to build your class extending CircularNotchedRectangle and override the getOuterPath(Rect host, Rect guest) to draw your custom path.I've done a small example :

class MyShape extends CircularNotchedRectangle{
  @override
  Path getOuterPath(Rect host, Rect guest) {
    if (guest == null || !host.overlaps(guest))
      return Path()..addRect(host);
      final double notchRadius = guest.width / 2.0;

      const double s1 = 8.0;
      const double s2 = 1.0;

      final double r = notchRadius;
      final double a = -1.0 * r - s2;
      final double b = host.top - guest.center.dy;

      final double n2 = math.sqrt(b * b * r * r * (a * a + b * b - r * r));
      final double p2xA = ((a * r * r) - n2) / (a * a + b * b);
      final double p2xB = ((a * r * r) + n2) / (a * a + b * b);
      final double p2yA = math.sqrt(r * r - p2xA * p2xA);
      final double p2yB = math.sqrt(r * r - p2xB * p2xB);

      final List<Offset> p = List<Offset>(6);

      // p0, p1, and p2 are the control points for segment A.    
      p[0] = Offset(a - s1, b);
      p[1] = Offset(a, b);
      final double cmp = b < 0 ? -1.0 : 1.0;
      p[2] = cmp * p2yA > cmp * p2yB ? Offset(p2xA,- p2yA) : Offset(p2xB, p2yB);

      // p3, p4, and p5 are the control points for segment B, which is a mirror
      // of segment A around the y axis.
      p[3] = Offset(-1.0 * p[2].dx, p[2].dy);
      p[4] = Offset(-1.0 * p[1].dx, p[1].dy);
      p[5] = Offset(-1.0 * p[0].dx, p[0].dy);

      // translate all points back to the absolute coordinate system.
      for (int i = 0; i < p.length; i += 1)
        p[i] += guest.center;
      return Path()
        ..moveTo(host.left, host.top)
        ..lineTo(p[1].dx, p[1].dy)
        ..arcToPoint(
          p[4],
          radius: Radius.circular(notchRadius),
          clockwise: true,
        )
        ..lineTo(host.right, host.top)
        ..lineTo(host.right, host.bottom)
        ..lineTo(host.left, host.bottom)
        ..close();
    }
}

Then you can use it in you BottomAppBar

Scaffold(
        appBar:AppBar(),
        body: Container(),
        bottomNavigationBar: BottomAppBar(
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              RaisedButton(onPressed:(){})
            ],
          ),

          notchMargin: 30.0,
          shape: MyShape(

          ),
          color:Colors.blue
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(onPressed:(){})
      ),
like image 117
Guru Prasad mohapatra Avatar answered Oct 29 '25 18:10

Guru Prasad mohapatra