flutter bottom navigation bar styling problem
Flutter has a specific shape for that kind of UI, it's called CircularNotchedRectangle. You can take the code of that class to see how the shape is drawn, build your custom shape from it, and tweak it to get the style you want, since it is pretty similar to CircularNotchedRectangle
. I wrote a little snippet that you can run in DartPad for you to see how to implement this in a BottomNavigationBar
. It might not be the exact same shape, but I think I got pretty close. It is impossible for me to get the exact shape without the parameters of that curve. Play around with the s1
, s2
, and addedRadius
parameters to get exactly what you want:
import 'dart:math' as math;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class CustomNotchedRectangle extends NotchedShape {
const CustomNotchedRectangle();
@override
Path getOuterPath(Rect host, Rect guest) {
if (guest == null || !host.overlaps(guest)) return Path()..addRect(host);
const double s1 = 10.0;
const double s2 = 8.0;
const double addedRadius = 3;
final double notchRadius = guest.width / 2.0 + addedRadius;
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);
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);
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);
for (int i = 0; i < p.length; i += 1) p[i] += guest.center;
return Path()
..moveTo(host.left, host.top)
..lineTo(p[0].dx, p[0].dy)
..quadraticBezierTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy)
..arcToPoint(
p[3],
radius: Radius.circular(notchRadius),
clockwise: false,
)
..quadraticBezierTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy)
..lineTo(host.right, host.top)
..lineTo(host.right, host.bottom)
..lineTo(host.left, host.bottom)
..close();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sample Code'),
),
body: Center(
child: Text('You have pressed the button $_counter times.'),
),
bottomNavigationBar: BottomAppBar(
shape: const CustomNotchedRectangle(),
child: Container(height: 50.0, color: Theme.of(context).primaryColor),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment Counter',
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
Here is the result:
Ghaith Chamieh
Updated on December 13, 2022Comments
-
Ghaith Chamieh over 1 year
This is the bottom navigation I am trying to do.
How i can implement this bottom navigation bar? I tried curved bottom navigation but it did not give me the solution and I tried flutter bottom navigation bar with fab center docked, but that also didn't work.
-
Bhargav Sejpal about 4 yearspub.dev/packages/curved_navigation_bar whats issue in this ?
-
drogel about 4 yearsYou mean that shape is not exactly the same as that of CircularNotchedRectangle?
-
Ghaith Chamieh about 4 yearswhen using curved_navigation_bar first of all i only have height of 75 , i can't customize the selected index and i can't anything behind the selected index which is not acceptable in this design i tried to use curved navigation I either used it wrong or it couldn't serve me well
-
Ghaith Chamieh about 4 yearsI meant i have 2 cases the unselected icon and the selected icon i should apply orange container to the selected icon which i can't do, also i want to see the screen behind the bottom navigation bar which I tried but i couldn't do that either
-
-
Ghaith Chamieh about 4 yearsI tried it but look at the curve it dose not looks like the photo i tried to change the curve layout but i couldn't... if you have any idea about changing the curve layout that would solve my problem
-
drogel about 4 yearsOkay, I see. Please review my edited answer, I think it might be useful for you.
-
Ghaith Chamieh about 4 yearsyes it is thx a-lot man even though i didn't understand the math but that brilliant